位和字节移位 C++

问题描述 投票:0回答:1

我有一个相当有趣的任务。我需要通过位的切除来执行位移位。也就是说,我有一个二进制 .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是程序的结果

c++ algorithm byte bit shift
1个回答
0
投票

当您写入以“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;
}
© www.soinside.com 2019 - 2024. All rights reserved.