开发者

Strip parity bits in C

Say I have a stream of bits with 8 bits of data followed by 2 parity bits (pattern repeats).

Example (x are parity bits):

0001 0001 xx00 0100 01xx 0001 0001 xx00 ...

should become

0001 0001 0001 0001 0001 0001 ...

I feel like this should be easy and I'm just over thinking it, but how do you go about stripping these parity bits?开发者_运维知识库


The tricky bit here is C doesn't let you work with bits easily, only bytes. I am going to assume that your char holds 8 bits (check CHAR_BIT in limits.h) -- this is the case on almost all modern systems. The least common multiple of 8 and 10 is 40, so you want to work in a buffer of at least 40 bits that you can do integer arithmetic on as a whole -- in practice that means a 64-bit type. So here's one way to do it, reading from stdin and writing to stdout. Handling streams that are not a multiple of 40 bits in length is left as an exercise.

#include <stdint.h>
#include <stdio.h>

int main(void)
{
    int c;
    uint_least64_t buffer;

    for (;;)
    {
       buffer = 0;
       /* read in 4 10-bit units = 5 8-bit units */
       c = getchar(); if (c == EOF) break;
       buffer = ((buffer << 8) | c);
       c = getchar(); if (c == EOF) break;
       buffer = ((buffer << 8) | c);
       c = getchar(); if (c == EOF) break;
       buffer = ((buffer << 8) | c);
       c = getchar(); if (c == EOF) break;
       buffer = ((buffer << 8) | c);
       c = getchar(); if (c == EOF) break;
       buffer = ((buffer << 8) | c);

       /* write out the non-parity bits */
       putchar((buffer & 0xFF00000000ULL) >> 32);
       putchar((buffer & 0x003FC00000ULL) >> 22);
       putchar((buffer & 0x00000FF000ULL) >> 12);
       putchar((buffer & 0x00000003FCULL) >>  2);
    }
    /* deal with incomplete block here */
    return 0;
}

... If you wanted to be really clever you would check those parity bits before you threw them away, although then you would have to come up with something constructive to do when (not if) the checksum failed.


I would define a bitfield struct in C, then use it to 'frame' the data buffer, extracting out just the useful bits. Something like this:

struct tframe {
     unsigned data: 8;
     unsigned control: 2;
}

struct tframe * frames = &buf;

/* Iterate and write 'data' field to wherever */
...

You are working with your own data so code portability will not be an issue.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜