Простой способ преобразовать строку из 0 и 1 в символ? Обычный C - PullRequest
4 голосов
/ 26 марта 2010

Я делаю стеганографический проект, в котором я читаю байты из файла ppm и добавляю младший значащий бит в массив. Таким образом, после считывания 8 байтов в моем массиве будет 8 бит, что должно равняться некоторому символу в скрытом сообщении. Есть ли простой способ преобразовать массив из 0 и 1 в значение ASCII? Например, массив: char bits[] = {0,1,1,1,0,1,0,0} будет равен 't'. Обычный C

Спасибо за все ответы. Я сделаю несколько снимков.

Ответы [ 4 ]

4 голосов
/ 26 марта 2010

Будет работать простой цикл for - что-то вроде


    unsigned char ascii = 0;
    unsigned char i;

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

Возможно, есть более быстрый способ сделать это, но это, по крайней мере, начало.

2 голосов
/ 26 марта 2010

Я бы не хранил биты в массиве - я бы ИЛИ их с символом.

Итак, вы начинаете со значения символа 0: char bit = 0;

Когда вы получите первый бит, ИЛИ с тем, что у вас есть: bit |= bit_just_read;

Продолжайте делать это с каждым битом, смещаясь соответствующим образом; после получения следующего бита, выполните bit |= (next_bit << 1);. И так далее.

После того, как вы прочитаете свои 8 битов, bit будет подходящим значением ASCII, и вы можете распечатать его или сделать с ним все, что захотите.

0 голосов
/ 26 марта 2010

До тех пор, пока bit endian верен, это должно работать и компилироваться довольно маленьким образом. Если битовый порядок равен обратному, то вы должны иметь возможность изменить начальное значение маски на 1, маска сместится на << =, и вам может потребоваться (0x0ff & mask) в качестве do {}, в то время как ваш условный компилятор не делает то, что должен делать с переменными размерами в байтах. Не забудьте сделать что-то для волшебных функций, которые я включил, где я не знал, что вы хотели или как вы что-то сделали </p>

#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++;
}
0 голосов
/ 26 марта 2010

Я согласен с mipadi, не надо сначала хранить в массиве, это бессмысленно. Поскольку вы должны зацикливаться или иным образом отслеживать индекс массива во время чтения, вы можете сделать это за один раз. Может быть, как-то так?

bits = 0;

for ( i = 0; i < 8; ++i ) {
    lsb = get_byte_from_ppm_somehow() & 0x01;
    bits <<= 1 | lsb;
}
...