在C中剥去奇偶校验位

时间:2011-06-30 16:31:28

标签: c

假设我有一个包含8位数据的位流,后跟2个奇偶校验位(模式重复)。

示例(x是奇偶校验位):

  

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

应该成为

  <0001> 0001 0001 0001 0001 0001 0001 ...

我觉得这应该很简单,我只是在想它,但是你如何去剥离这些奇偶校验位呢?

2 个答案:

答案 0 :(得分:6)

这里棘手的一点是C不会让你轻松使用位,只有字节。我将假设您的char保留8位(在CHAR_BIT中检查limits.h) - 几乎所有现代系统都是如此。 8和10的最小公倍数是40,所以你想在至少40位的缓冲区中工作,你可以在整体上进行整数运算 - 实际上这意味着64位类型。所以这是一种方法,从stdin读取并写入stdout。处理长度不是40位的倍数的流将留作练习。

#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;
}

...如果你想要变得非常聪明,那么在你把它们扔掉之前你会检查那些奇偶校验位,尽管那时你必须想出一些建设性的东西(不是如果)校验和失败了。

答案 1 :(得分:-1)

我将在C中定义一个位域结构,然后用它来“构建”数据缓冲区,只提取有用位。像这样:

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

struct tframe * frames = &buf;

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

您正在使用自己的数据,因此代码可移植性不会成为问题。