切换位,但不将它们切换回来?
Switch Bits, but does not switch them back?
我正在处理一些代码并决定尝试在文件中切换一些位,然后将它们切换回来以获取原始文件。不知何故,它改变了位,但不会将它们改回来。
这是我的资料:
魔术发生在我打开一个文件并读入 rByte[0] 和 rByte[1] 时。
unsigned char rByte[] = {0, 0};
int isBitSet(unsigned char byte, int bytePosition){
unsigned char mask[] = {128, 64, 32, 16, 8, 4, 2, 1};
return ( (byte & mask[bytePosition]) != 0 );
}
unsigned char setBit(unsigned char byte, int pos) {
byte |= (0x01 << pos);
return byte;
}
unsigned char clearBit(unsigned char byte, int pos){
byte &= ~(0x01 << pos);
return byte;
}
/* DO NOT TOUCH */
void switchBits (unsigned char byte1, unsigned char byte2, int x, int y) {
int reg1 = 0;
int reg2 = 0;
reg1 = isBitSet(byte1, x);
reg2 = isBitSet(byte2, y);
if ( (reg1 == reg2) ) {
}
if ( (reg1 == 0) && (reg2 != 0) ){
rByte[0] = setBit(byte1, x);
rByte[1] = clearBit(byte2, y);
}
if( (reg2 == 0) && (reg1 != 0) ){
rByte[0] = clearBit(byte1, x);
rByte[1] = setBit(byte2, y);
}
}
现在,我假设如果应用相同的 switchBits()
,按照我的看法,程序应该恢复正常。我制作了一个音乐文件,发出奇怪的声音,但没有恢复正常。
假设 rByte
是全局定义的(这不太好)。
与 setBit()
和 clearBit()
相比,您在 isBitSet()
中的位位置颠倒了。
示例假设 pos = 0
isBitSet
将 MSB(最高有效位)检查为 mask[0] == 128
但在 setBit
和 clearBit
函数中,您移动 0x01 << 0
意味着它对应于 1
.
编辑:
我建议你改变
unsigned char mask[] = {128, 64, 32, 16, 8, 4, 2, 1};
到
unsigned char mask[] = {1, 2, 4, 8, 16, 32, 64, 128};
编辑结束
你应该考虑一下你的函数设计,只是链接 if
s 看起来很奇怪,你想要实现的逻辑可以改进。这里有一个简化逻辑的例子,你可以用另一种方式来更具体地说明逻辑,所以这只是一个建议。
if ( (reg1 == reg2) ) {
}
else{
if ( (reg1 == 0)){
rByte[0] = setBit(byte1, x);
rByte[1] = clearBit(byte2, y);
}
else{
rByte[0] = clearBit(byte1, x);
rByte[1] = setBit(byte2, y);
}
}
另一个可以再次简化程序的东西是一个 switch 函数,它只是从 1
中生成 0
,反之亦然。 XOoperator ^
很容易做到这一点。意思是如果两者不同,你只需要切换两个位的状态,这样它就会将你的功能减少到这个。
if ( (reg1 != reg2) ) {
rByte[0] = switchBit(byte1,x);
rByte[1] = switchBit(byte2,y);
}
我正在处理一些代码并决定尝试在文件中切换一些位,然后将它们切换回来以获取原始文件。不知何故,它改变了位,但不会将它们改回来。
这是我的资料:
魔术发生在我打开一个文件并读入 rByte[0] 和 rByte[1] 时。
unsigned char rByte[] = {0, 0};
int isBitSet(unsigned char byte, int bytePosition){
unsigned char mask[] = {128, 64, 32, 16, 8, 4, 2, 1};
return ( (byte & mask[bytePosition]) != 0 );
}
unsigned char setBit(unsigned char byte, int pos) {
byte |= (0x01 << pos);
return byte;
}
unsigned char clearBit(unsigned char byte, int pos){
byte &= ~(0x01 << pos);
return byte;
}
/* DO NOT TOUCH */
void switchBits (unsigned char byte1, unsigned char byte2, int x, int y) {
int reg1 = 0;
int reg2 = 0;
reg1 = isBitSet(byte1, x);
reg2 = isBitSet(byte2, y);
if ( (reg1 == reg2) ) {
}
if ( (reg1 == 0) && (reg2 != 0) ){
rByte[0] = setBit(byte1, x);
rByte[1] = clearBit(byte2, y);
}
if( (reg2 == 0) && (reg1 != 0) ){
rByte[0] = clearBit(byte1, x);
rByte[1] = setBit(byte2, y);
}
}
现在,我假设如果应用相同的 switchBits()
,按照我的看法,程序应该恢复正常。我制作了一个音乐文件,发出奇怪的声音,但没有恢复正常。
假设 rByte
是全局定义的(这不太好)。
与 setBit()
和 clearBit()
相比,您在 isBitSet()
中的位位置颠倒了。
示例假设 pos = 0
isBitSet
将 MSB(最高有效位)检查为 mask[0] == 128
但在 setBit
和 clearBit
函数中,您移动 0x01 << 0
意味着它对应于 1
.
编辑: 我建议你改变
unsigned char mask[] = {128, 64, 32, 16, 8, 4, 2, 1};
到
unsigned char mask[] = {1, 2, 4, 8, 16, 32, 64, 128};
编辑结束
你应该考虑一下你的函数设计,只是链接 if
s 看起来很奇怪,你想要实现的逻辑可以改进。这里有一个简化逻辑的例子,你可以用另一种方式来更具体地说明逻辑,所以这只是一个建议。
if ( (reg1 == reg2) ) {
}
else{
if ( (reg1 == 0)){
rByte[0] = setBit(byte1, x);
rByte[1] = clearBit(byte2, y);
}
else{
rByte[0] = clearBit(byte1, x);
rByte[1] = setBit(byte2, y);
}
}
另一个可以再次简化程序的东西是一个 switch 函数,它只是从 1
中生成 0
,反之亦然。 XOoperator ^
很容易做到这一点。意思是如果两者不同,你只需要切换两个位的状态,这样它就会将你的功能减少到这个。
if ( (reg1 != reg2) ) {
rByte[0] = switchBit(byte1,x);
rByte[1] = switchBit(byte2,y);
}