Search code examples
cmemory-mapped-filesmemory-mapping

How do I properly byte shift a chunk of data?


I have a mmap

void *mymap;
mymap = mmap(0, attr.st_size, PROT_READ|PROT_WRITE, MAPFILE|MAP_SHARED, fd, 0);

I opened a file with the HEX content 0x25362364 which is

00100101001101100010001101100100

in binary. Now I want to perform a bit shift:

char *str = (char *)mymap;
for(int i=0;i<attr.st_size;i++) {
    str[i] = str[i] >> 4;
}

my new file contains the new binary number

00000010000000110000001000000110

but the wished result was to shift everything 4 bits to the right:

00000010010100110110001000110110

how can I accomplish this? bonus question: if the binary numbers MSB is a 1 how can I have the left side filled up with 0's when shifting right?


Solution

  • Each byte in the array should be shifted right by 4 bits and ORred with the previous (unsigned) byte shifted left by 4 bits. For example

    unsigned char *str = (unsigned char *)mymap;
    unsigned char prev = 0, next;
    for(int i = 0; i < attr.st_size; i++) {
        next  = str[i];
        str[i] = (str[i] >> 4) | (prev << 4);
        prev = next;    
    }
    

    In the case where you want a right shift of 5 bits, you would shift right by 5 bits and left by 3 bits, sum = 8 (assuming CHAR_BIT is 8).