通过编辑数组元素的最后一位来编码数字

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.