我有一个相当有趣的任务。我需要通过位的切除来执行位移位。也就是说,我有一个二进制 .bin 文件。前16个字节必须被跳过,字节编号从0开始,然后从17个字节中削减3位,140 141和142位。并将整个序列移位这 3 位,然后跳过 32 个字节,再次从该字节中剪切 3 位,并再次移位序列。我有点不明白当你需要移位超过 1 个字节时如何进行移位。条件还表明程序应该是高效的。在不到一分钟的时间内,您需要处理一个大约 5000 万字节的文件。因此,不存在嵌套循环等。
这是我得到的示例代码,我认为我正在朝着正确的方向前进,但我不明白如何正确移动超过 1 个字节。
#include <iostream>
#include <fstream>
#include <vector>
#include <bitset>
std::vector<uint8_t> Shift(std::vector<uint8_t>& src, int val, bool left) {
std::vector<uint8_t> res(src.size());
int byteShift = val >> 3;
uint8_t mask = ~(0b111 << 1);
if (byteShift >= src.size())
return res;
val = 3;
res.insert(res.begin(), src.begin(), src.begin() + 17); // Copy the first 17 bytes unchanged
int j = 1;
for (size_t i = 17; i < src.size()-j; i++) {
if ((i - 16) % 32 == 0 && i != 17) {
res[i + j] = static_cast<uint8_t>((src[i + j] &= mask)>>3 | src[i + j + 1] << 5);
res[i] = static_cast<uint8_t>(((src[i] >> 3) | res[i + j] << 8 - val));
res[i + j] = static_cast<uint8_t>(((res[i + j] >> val) | src[i + j + 1] << 8 - val));
res[i] = static_cast<uint8_t>(((res[i] >> val) | res[i + j] << 8 - val));
switch (val)
{
case 1:
val = 4;
break;
case 2:
val = 5;
break;
case 3:
val = 6;
break;
case 4:
val = 7;
break;
case 5:
val = 8;
break;
case 6:
val = 1;
j++;
break;
case 7:
val = 2;
j++;
break;
case 8:
val = 3;
j++;
break;
}
}
else {
res[i] = static_cast<uint8_t>((src[i] >> val) | src[i + j] << (8 - val));
}
}
return res;
}
int main() {
const std::string inputFileName = "F:/C++ Progect/ConsoleApplication5/ConsoleApplication5/x64/Debug/0_1.bin";
const std::string outputFileName = "output.bin";
const int shiftValue = 3;
const bool shiftLeft = false; // Change to false for right shift
try {
std::ifstream inputFile(inputFileName, std::ios::binary);
if (!inputFile)
throw std::runtime_error("The input file could not be opened.");
inputFile.seekg(0, std::ios::end);
std::streampos fileSize = inputFile.tellg();
inputFile.seekg(0, std::ios::beg);
std::vector<uint8_t> inputData(fileSize);
inputFile.read(reinterpret_cast<char*>(inputData.data()), fileSize);
std::vector<uint8_t> shiftedData = Shift(inputData, shiftValue, shiftLeft);
std::ofstream outputFile(outputFileName, std::ios::binary);
if (!outputFile)
throw std::runtime_error("The output file could not be created.");
outputFile.write(reinterpret_cast<const char*>(shiftedData.data()), shiftedData.size());
std::cout << "The shift was completed successfully." << std::endl;
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
return 1;
}
return 0;
}
https://drive.google.com/drive/folders/1hC4kwNwTLT9tZG6uFiHy8VT-V_8zPZGh?usp=sharing
我附上了一个带有源文件的谷歌驱动器链接,并且应该出现的链接,0_1是源文件,1_1是程序的结果
当您写入以“0b”开头的位时,请尝试以 8/16/32/64 位长度写入它们,而不是 3、4 或 5,因为它可能不会被视为 3 位变量,而是被视为8/16/32/64 位变量。它可能会将 0b111 视为 0b11100000 或 0b00011111。
这是位移位工作原理的演示,尽管您可能会发现它无关紧要。
using namespace std;
int main()
{
bitset <8> x;
cout << "Bitshifting 00000001 right to left" << endl;
cout << "Nr of Shifts | Result" << endl;
for (unsigned int i = 0; i < 9; i++) {
x = (0 | (0b00000001 << i));
cout << i << " | " << x << endl;
}
cout << endl;
cout << "Bitshifting 00000001 left to right" << endl;
cout << "Nr of Shifts | Result" << endl;
for (unsigned int i = 0; i < 9; i++) {
x = (0 | (0b00000001 >> i));
cout << i << " | " << x << endl;
}
return 0;
}