我正在做一个隐写术项目,我从 ppm 文件中读取字节并将最低有效位添加到数组中。因此,一旦读入 8 个字节,我的数组中就会有 8 位,这应该等于隐藏消息中的某个字符。有没有一种简单的方法可以将 0 和 1 的数组转换为 ascii 值?例如,数组:char bits[] = {0,1,1,1,0,1,0,0}
将等于 't'。纯C
感谢所有的答案。我要试一试这些。
一个简单的for
循环就可以了——比如
unsigned char ascii = 0;
unsigned char i;
for(i = 0; i < 8; i++)
ascii |= (bits[7 - i] << i);
可能有更快的方法来做到这一点,但这至少是一个开始。
我不会将这些位存储在一个数组中——我会用一个字符对它们进行 OR 运算。
所以你从 0 的 char 值开始:char bit = 0;
当你得到第一个比特时,或者它与你所拥有的:bit |= bit_just_read;
对每一位继续这样做,适当地移动;即,在你得到下一点之后,做bit |= (next_bit << 1);
. 等等。
在你读完你的 8 位之后,bit
将是适当的 ASCII 值,你可以将它打印出来或做任何你想做的事情。
我同意 mipadi,不要先存储在数组中,这有点毫无意义。由于您必须在读取数组索引时循环或以其他方式跟踪它,因此您不妨一口气完成。大概是这样的吧?
bits = 0;
for ( i = 0; i < 8; ++i ) {
lsb = get_byte_from_ppm_somehow() & 0x01;
bits <<= 1 | lsb;
}
只要位端是正确的,这应该可以工作并且编译得非常小。如果位字节序是向后的,那么您应该能够将掩码的初始值更改为 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++;
}