一点一点地写一个文件

Write a file bit by bit

基本上我正在尝试读取一个文件,每 4 位序列更改最后一位,然后读取更改后的文件并将其恢复为原始文件。 是 test1.bin -> test2.bin -> test3.bin 00011100 -> 00001101 -> 00011100 然而,虽然第二个文件没问题,但第三个文件每 8 个而不是 4 个改变一点。这是

int main(int argc, char** argv) {   
    ifstream f("C:\Users\simon\Desktop\test\test.bin", ios::binary | ios::in);
    ofstream f_o("C:\Users\simon\Desktop\test\test2.bin", ios::binary | ios::out);
    char c,app;

    int rund=0;
    while (f.get(c)){
        app=c;
        for (int i = 7; i >= 0; i--){
            if(rund==3){ //it's the 4th bit, I change it
                rund=0;
                if(((c >> i) & 1) == 0)  app |= 1 << i; //if it's 0 i change to 1
                else  app |= 0 << i;
                }   
            else  rund += 1;
        }
        f_o.put(app); 
    }

    f.close();
    f_o.close();

    ifstream f2("C:\Users\simon\Desktop\test\test2.bin", ios::binary | ios::in);
    ofstream f_o2("C:\Users\simon\Desktop\test\test3.bin", ios::binary | ios::out);

    rund=0;
    while (f2.get(c)){
        app=c;
        for (int i = 7; i >= 0; i--){ 
            if(rund==3){
                rund=0;
                if(((c >> i) & 1) == 0)  app |= 1 << i;
                else  app |= 0 << i;
                } 
            else  rund += 1;     
        }
        f_o2.put(app); 
    }

}

KIIV 已经有效地为您提供了(非常简单的)解决方案,所以我将展示它的实际效果并解释它为什么有效(我无法抗拒,这里的代码减少太漂亮了,而且我并不羞于承认我喜欢 xor。)

新代码:

int main(int argc, char** argv) {   
    ifstream f("C:\Users\simon\Desktop\test\test.bin", ios::binary | ios::in);
    ofstream f_o("C:\Users\simon\Desktop\test\test2.bin", ios::binary | ios::out);
    char c;

    while (f.get(c))
        f_o.put(c ^ 0x11);

    f.close();
    f_o.close();

    ifstream f2("C:\Users\simon\Desktop\test\test2.bin", ios::binary | ios::in);
    ofstream f_o2("C:\Users\simon\Desktop\test\test3.bin", ios::binary | ios::out);

    while (f2.get(c))
        f_o2.put(c ^ 0x11);   
}

按位异或 (XOR)

运算符 ^ 执行按位异或,又名 'XOR' 运算。它按位(按位!)工作,如下所示:

0 ^ 0 -> 0
0 ^ 1 -> 1
1 ^ 0 -> 1
1 ^ 1 -> 0

换句话说,如果A,B中只有一个为1,则A ^ B为1。因此'exclusive'或.

位翻转 ^

Xor 是一个非常有趣的按位运算。除了其他有趣的属性,当您需要 'flip' 位的状态(即将 1 映射到 0 或 0 映射到 1)时,它是完美的工具。

假设我选择 A ^ 1。如果 A 为 0,则我有 0 ^ 1 = 1。如果 A 为 1,则我有 1 ^ 1 = 0。所以你看,如果我用 1 异或,我实际上 'flip' 这个位。

OTOH,假设我选择 A ^ 0。如果 A 为 0,则我有 0 ^ 0 = 0。如果 A 为 1,则我有 1 ^ 0 = 1。换句话说,A ^ 0 = A!

这是一个完美的情况...我们可以构建一个位串来与您的字节进行异或运算,并且该位串中的每一位都将决定您的字节中的相应位是否被翻转!

0x11

唯一需要了解的是如何创建翻转所需位所需的值。你想翻转第 4 位和第 8 位。所以我们需要构造00010001。如果您知道十六进制,您会立即清楚这是 0x11。如果没有,请使用在线转换器,然后在完成此项目后去学习十六进制..voila :)