我正在尝试用C编写一个简单的编码程序,我的按位操作肯定有问题,所以我试着写一个简化的版本来解决这个错误 - 到目前为止它还没有用。我有一种编码和解码方法,给定一个“密钥”,我通过将一些数字隐藏在一大堆无符号整数中来编码一个数字。
我通过使用srand(key)隐藏它(这样我可以使用相同的键生成相同的数字后缀)选择数组元素然后取一位数(迭代全部)并交换数组元素的最低位有点过来了。
在解码方法中,我尝试反转这些步骤,从数组元素中获取所有位并将它们粘合在一起以获取原始数字。
那是我到目前为止的代码:
unsigned int * encode(unsigned int * original_array, char * message, unsigned int mSize, unsigned int secret) {//disregard message, that's the later part, for now just encoding mSize - size of message
int size = MAX; //amount of elementas in array, max defined at top
int i, j, tmp;
unsigned int *array;
srand(secret); //seed rand with the given key
array = (unsigned int *)malloc(MAX*sizeof(unsigned int));
//copy to array from im
for (i=0; i<MAX; i++){
array[i] = original_array[i];
}
//encode message length first. it's a unsigned int therefore it's size is 4 bytes - 32 bits.
for (i=0; i<32; i++){
tmp = rand() % size;
if (((mSize >> i) & 1)==1) //check if the bit is 1
array[tmp] = (1 << 0) | array[tmp]; // then write 1 as last bit
else //else bit is 0
array[tmp] = array[tmp] & (~(1 << 0)); //write 0 as last bit
}
return array;
}
unsigned int decode(unsigned int * im, unsigned int secret) {
char * message;
int i, tmp;
unsigned int result = 2;
int size = MAX;
srand(secret);
for (i=0; i<32; i++){
tmp = rand() % size;
if (((im[tmp] << 0) & 1)==1)
result = (1 >> i) | result;
else
result = result & (~(1 >> i));
}//last
return result;
}
然而,运行它并尝试打印解码结果将给出2,这是我给出的导致decode()的虚拟值 - 因此我知道至少我恢复更改位的方法显然不起作用。不幸的是,由于解码不起作用,我不知道编码是否真的有效,我似乎无法查明错误。
我试图理解这些位的隐藏是如何起作用的,因为最终,我想在一个稍微复杂的结构中隐藏整个消息然后数组,但首先我想让它在更简单的层面上工作,因为我遇到了麻烦按位运算符。
编辑:通过一些调试我认为编码功能正常工作 - 或者至少看起来似乎有时将数组元素改为1,这表示如果满足条件则翻转一位。解码似乎根本不会影响result
变量 - 它不会改变所有按位操作,我不知道为什么。
编码功能的主要部分如下所示,通过删除不必要的0移位和括号,与原始编辑功能相同,只需稍微整理一下:
//encode message length first. it's a unsigned int therefore it's size is 4 bytes - 32 bits.
for (i=0; i<32; i++){
tmp = rand() % size;
if (((mSize >> i) & 1)==1) //check if the bit is 1
array[tmp] |= 1; // then write 1 as last bit
else //else bit is 0
array[tmp] &= ~1; //write 0 as last bit
}
您遇到的问题是,如果您将最后一位设置为1或0,那么您实际上会丢失信息。没有办法说出原来的最后一点是什么。所以你将无法解码或逆转它。
简而言之,解码功能永远不会起作用。由于编码功能不可逆。
编辑
继续你的评论。我会说以下关于解码功能(再次整理它应该与原始相同):
unsigned int decode(unsigned int * im, unsigned int secret) {
char * message;
int i, tmp;
unsigned int result = 2;
int size = MAX;
srand(secret);
for (i=0; i<32; i++){
tmp = rand() % size;
if ((im[tmp] & 1)==1)
result |= 1 >> i;
else
result &= ~(1 >> i);
}//last
return result;
}
这里需要注意的是,对于i> 0的所有值,以下内容适用:
1 >> i
是相同的
0
这意味着对于大多数循环,代码将执行以下操作
if ((im[tmp] & 1)==1)
result |= 0;
else
result &= ~0;
因为2 = 2 | 0和2 = 2&〜0然后无论if的哪个分支被执行,结果将始终为2.这对于任何偶数都是相同的。
当i = 0时,则情况如下:
if ((im[tmp] & 1)==1)
result |= 1;
else
result &= ~1;
因此2 | 1 = 3和2&~1 = 2您的解码功能将只返回2或偶尔返回3。