Question

I'm doing a steganography project where I read in bytes from a ppm file and add the least significant bit to an array. So once 8 bytes are read in, I would have 8 bits in my array, which should equal some character in a hidden message. Is there an easy way to convert an array of 0's and 1's into an ascii value? For example, the array: char bits[] = {0,1,1,1,0,1,0,0} would equal 't'. Plain C

Thanks for all the answers. I'm gonna give some of these a shot.

Was it helpful?

Solution

A simple for loop would work - something like


    unsigned char ascii = 0;
    unsigned char i;

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

There might be a faster way to do this, but this is a start at least.

OTHER TIPS

I wouldn't store the bits in an array -- I'd OR them with a char.

So you start off with a char value of 0: char bit = 0;

When you get the first bit, OR it with what you have: bit |= bit_just_read;

Keep doing that with each bit, shifting appropriately; i.e., after you get the next bit, do bit |= (next_bit << 1);. And so forth.

After you read your 8 bits, bit will be the appropriate ASCII value, and you can print it out or do whatever with it you want to do.

I agree with mipadi, don't bother storing in an array first, that's kind of pointless. Since you have to loop or otherwise keep track of the array index while reading it in, you might as well do it in one go. Something like this, perhaps?

bits = 0;

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

As long as the bit endian is correct, this should work and compile down pretty small. If the bit endian is backwards then you should be able to change the initial value of mask to 1, the mask shift to <<= , and you might need to have (0x0ff & mask) as the do{}while conditional if your compiler doesn't do what it's supposed to with byte sized variables. Don't forget to do something for the magic functions that I included where I didn't know what you wanted or how you did something

#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++;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top