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

时间:2019-02-26 11:17:36

标签: c bit-manipulation bit

我正在尝试用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()-因此,我知道至少我的恢复已更改位的方法显然不起作用。不幸的是,由于解码不起作用,所以我不知道编码是否真的有效,而且我似乎无法指出错误。

我试图了解这些位的隐藏是如何工作的,因为最终,我希望将整个消息隐藏在比数组稍微复杂的结构中,但是首先,我想使其更简单地工作,因为使用按位运算符会遇到麻烦。

编辑:通过一些调试,我认为编码功能可以正常工作-或至少似乎确实将数组元素更改了一个,这有时表示如果满足条件,则将其翻转一位。 解码似乎根本不会影响result变量-它不会改变所有按位操作的方式,而且我也不知道为什么。

1 个答案:

答案 0 :(得分:1)

encode函数的主要功能如下,与您原来的功能相同:去除了不必要的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。