4

我正在做一个隐写术项目,我从 ppm 文件中读取字节并将最低有效位添加到数组中。因此,一旦读入 8 个字节,我的数组中就会有 8 位,这应该等于隐藏消息中的某个字符。有没有一种简单的方法可以将 0 和 1 的数组转换为 ascii 值?例如,数组:char bits[] = {0,1,1,1,0,1,0,0}将等于 't'。纯C

感谢所有的答案。我要试一试这些。

4

4 回答 4

4

一个简单的for循环就可以了——比如


    unsigned char ascii = 0;
    unsigned char i;

    for(i = 0; i < 8; i++)
       ascii |= (bits[7 - i] << i);

可能有更快的方法来做到这一点,但这至少是一个开始。

于 2010-03-26T05:10:18.300 回答
2

我不会将这些位存储在一个数组中——我会用一个字符对它们进行 OR 运算。

所以你从 0 的 char 值开始:char bit = 0;

当你得到第一个比特时,或者它与你所拥有的:bit |= bit_just_read;

对每一位继续这样做,适当地移动;即,在你得到下一点之后,做bit |= (next_bit << 1);. 等等。

在你读完你的 8 位之后,bit将是适当的 ASCII 值,你可以将它打印出来或做任何你想做的事情。

于 2010-03-26T05:11:57.867 回答
0

我同意 mipadi,不要先存储在数组中,这有点毫无意义。由于您必须在读取数组索引时循环或以其他方式跟踪它,因此您不妨一口气完成。大概是这样的吧?

bits = 0;

for ( i = 0; i < 8; ++i ) {
    lsb = get_byte_from_ppm_somehow() & 0x01;
    bits <<= 1 | lsb;
}
于 2010-03-26T06:05:14.033 回答
0

只要位端是正确的,这应该可以工作并且编译得非常小。如果位字节序是向后的,那么您应该能够将掩码的初始值更改为 1,掩码转换为 <<= ,并且如果您的编译器有条件,您可能需要 (0x0ff & mask) 作为 do{}对字节大小的变量没有做它应该做的事情。不要忘记为我包含的魔术功能做一些事情,我不知道你想要什么或你是如何做某事的

#include <stdint.h> // needed for uint8_t
...
uint8_t acc, lsb, mask;
uint8_t buf[SOME_SIZE];
size_t len = 0;

while (is_there_more_ppm_data()) {
    acc = 0;
    mask = 0x80; // This is the high bit
    do {
         if (!is_there_more() ) {
             // I don't know what you think should happen if you run out  on a non-byte boundary
             EARLY_END_OF_DATA();
             break;
         }
         lsb = 1 & get_next_ppm_byte();
         acc |= lsb ? mask : 0; // You could use an if statement
         mask >>= 1;
    } while (mask);
    buf[len] = acc; // NOTE: I didn't worry about the running off the end of the buff, but you should. 
    len++;
}
于 2010-03-26T17:55:00.880 回答