通过编辑数组元素的最后一位来编码数字
Encoding number through editing last bit of array elements
我正在尝试用 C 编写一个简单的编码程序,但我的按位运算肯定有问题,所以我尝试编写一个简化版本来修复该错误 - 到目前为止它仍然无法正常工作。我有一种编码和解码方法,其中,给定一个 "key" 我通过将一个数字的位隐藏在一个大的无符号整数数组中来编码它。
我通过使用 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() 中给出的虚拟值 - 因此我知道至少我恢复更改位的方法显然是行不通的。不幸的是,由于解码不起作用,我不知道编码是否真的有效,而且我似乎无法查明错误。
我试图了解隐藏这些位的工作原理,因为最终我想将整个消息隐藏在比数组稍微复杂的结构中,但首先我想让它在更简单的级别上工作,因为我在使用按位运算符时遇到了麻烦。
编辑:通过一些调试,我认为编码函数工作正常——或者至少有时似乎确实将数组元素更改了一个,这表明如果满足条件则翻转一位。
解码似乎根本不会影响 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 and 2 = 2 & ~0 那么无论执行 if 的哪个分支,结果都将始终为 2。这对于任何偶数都是相同的。
当i = 0时,情况如下:
if ((im[tmp] & 1)==1)
result |= 1;
else
result &= ~1;
自从 2 | 1 = 3 and 2 & ~1 = 2 你的解码函数只会 return 2 或偶尔 3.
我正在尝试用 C 编写一个简单的编码程序,但我的按位运算肯定有问题,所以我尝试编写一个简化版本来修复该错误 - 到目前为止它仍然无法正常工作。我有一种编码和解码方法,其中,给定一个 "key" 我通过将一个数字的位隐藏在一个大的无符号整数数组中来编码它。
我通过使用 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() 中给出的虚拟值 - 因此我知道至少我恢复更改位的方法显然是行不通的。不幸的是,由于解码不起作用,我不知道编码是否真的有效,而且我似乎无法查明错误。
我试图了解隐藏这些位的工作原理,因为最终我想将整个消息隐藏在比数组稍微复杂的结构中,但首先我想让它在更简单的级别上工作,因为我在使用按位运算符时遇到了麻烦。
编辑:通过一些调试,我认为编码函数工作正常——或者至少有时似乎确实将数组元素更改了一个,这表明如果满足条件则翻转一位。
解码似乎根本不会影响 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 and 2 = 2 & ~0 那么无论执行 if 的哪个分支,结果都将始终为 2。这对于任何偶数都是相同的。
当i = 0时,情况如下:
if ((im[tmp] & 1)==1)
result |= 1;
else
result &= ~1;
自从 2 | 1 = 3 and 2 & ~1 = 2 你的解码函数只会 return 2 或偶尔 3.