【问题标题】:Encoding number through editing last bit of array elements通过编辑数组元素的最后一位编码数字
【发布时间】:2019-07-19 22:13:34
【问题描述】:

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

【问题讨论】:

  • 为什么要按位移位 0?以下代码看起来很奇怪:im[tmp]
  • 您可以在调试器中运行您的程序并检查在编码期间创建了哪些值。当您定义算法时,您应该能够验证结果值与预期值
  • @Tom Maher 谈到 (im[tmp]
  • @Gergardh 我试试调试,不知什么原因忘记了,看看能找到什么
  • @Gergardh 到目前为止,我知道 encode 正在更改一些值(它们相差 1,这意味着最后一位有时会切换为 1 或 0 并更改值)所以它似乎确实有效,至少在某种程度上。我仍然不知道为什么解码不会在整个过程中改变结果编号,因为我认为这是问题所在(当然可能是错误的)。

标签: c bit-manipulation bit


【解决方案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 时,您实际上会丢失信息。没有办法知道原来的最后一点是什么。所以你将无法解码或反转它。

简而言之,解码功能永远不会起作用。因为encode函数是不可逆的。

编辑

从您的评论开始。关于解码功能我想说以下(再次整理一下应该和原来的一样):

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 >> 我

相同

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 and 2 & ~1 = 2 您的解码函数只会返回 2 或偶尔返回 3。

【讨论】:

  • 感谢您的清理,它确实使它看起来更好。但是我不需要再次查看原始位 - 一旦我更改它们,我只想访问更改的那些,因为它们应该形成我编码的消息。原始数组并不重要,我不再需要它了——我只想将改变的位重新形成我编码的内容。当前的问题是 decode 根本不会改变结果 - 尽管在按位运算中使用它,但它仍然是虚拟值。
  • @Shinigami 我更新了我的答案,指出为什么解码函数只返回 2(有时是 3)。
  • 非常感谢,我不知道我怎么错过了这么久
  • 您可以将if((im[tmp] &amp; 1)==1) 部分缩短为if(im[tmp] &amp; 1),因为如果该位是1,那么== 的LHS 将评估为1,这被认为是“真” ”。相同的逻辑可以应用于if(((mSize &gt;&gt; i) &amp; 1)==1) 部分:if((mSize &gt;&gt; i) &amp; 1)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-07
  • 2017-10-06
  • 2013-02-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多