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

问题描述 投票:0回答:1

我正在尝试用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变量 - 它不会改变所有按位操作,我不知道为什么。

c bit-manipulation bit
1个回答
1
投票

编码功能的主要部分如下所示,通过删除不必要的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。

© www.soinside.com 2019 - 2024. All rights reserved.