2009-12-08 23 views
3

我有一个数据流只能以8位字节寻址,我想将其解析为6位元素并将其存储到数组中。有没有最好的方法来做到这一点?如何解析字节可寻址数组中的n位元素

11110000 10101010 11001100 

111100|001010|101011|001100 

的阵列(可以具有零填充,只是需要寻址这样)

和数据是一个8位的阵列,其也是6位的倍数,并不是真正的无穷无尽

+0

这是5位数据元素的一个常数,层出不穷,或公知的结构,其重复? – qid 2009-12-08 22:19:42

+0

也许有一些纠错冗余,总是假设最好;-) – hirschhornsalz 2009-12-08 22:50:49

+0

这些字节写入最低有效位第一或最重要?换句话说,是(15,85,51)还是(240,170,204)? – 2009-12-08 23:05:20

回答

8

依赖于一个字节多少位对您的具体架构。上6位架构是很简单的:-)

假设每个字节架构的8位,你将不得不做沿着线的东西:

int sixbits(unsigned char* datastream, unsigned int n) { 
    int bitpos = n*6; 
    return (datastream[bitpos/8] >> bitpos%8) // lower part of the five bit group 
     + (datastream[bitpos/8+1] << 8-bitpos%8) // if bitpos%8>2, we need to add some carry bits from the next char 
     & 0x3f;         // and finally mask the lowest 6 bits 
} 

其中n是第n个6位组。任何体面的编译器都会用shift和带有ands的模来代替分割。只需在循环中使用此函数来填充目标数组。

+0

+1好的解决方案,比我的快得多。不过你可能想修正'error:'index'undeclared'。 – 2009-12-08 22:43:18

+0

谢谢,修正。删除了一些不必要的括号,以便为注释提供更多地方;对于非C语言的人员,优先级应该用额外的空格来清楚。 – hirschhornsalz 2009-12-08 22:52:10

+0

太好了,谢谢你比我的口才多 – stbtra 2009-12-09 01:18:12

1

你计数你的5位序列,读ea ch字节,根据您的计数器和期望的字位置(通过异或来自相邻字节字的字符)来移位位,并形成新的正确对齐的字节字,然后再处理。

我希望你不要指望代码...

0

如何使用一个结构是这样的:

struct bit5 
{ 
    unsigned int v1 : 5; 
    unsigned int v2 : 5; 
    unsigned int v3 : 5; 
    unsigned int v4 : 5; 
    unsigned int v5 : 5; 
    unsigned int v6 : 5; 
    unsigned int v7 : 5; 
    unsigned int v8 : 5; 
}; 

然后投你的字节数组到struct bit5每8个字节(40位= 8组,每组5位的,适合在8个字节)来获得5位块。你说:

unsigned char* array; // a byte array that you want to convert 
int i; 
struct bit5* pBit5; 

for(i = 0; i < (int)(SIZE_OF_ARRAY/8); i++) 
    pBit5 = (struct bit5*)((int)array + i * 8); 
1

可以使用位摆弄做到这一点:

#include <stdio.h> 
#include <string.h> 

int main(int argc, char *argv[]) 
{ 
    unsigned char source[3] = { 15, 85, 51 }; 
    unsigned char destination[4]; 
    memset(destination, 0, 4); 
    for (int i = 0; i < (8 * 3); ++i) 
    { 
     destination[i/6] |= ((source[i/8] >> (i % 8) & 1) << (i % 6)); 
    } 

    for (int j = 0; j < 4; ++j) 
     printf("%d ", destination[j]); 
} 

输出:

15 20 53 12 

注意,这开始从五个至少显著位工作。

 15  85  51 
11110000 10101010 11001100 
111100 001010 101011 001100 
    15  20  53  12 

为了获得最显著第一,这样做,而不是:

destination[i/6] |= ((source[i/8] >> (7 - (i % 8))) & 1) << (5 - (i % 6)); 

这可以作为你的榜样,假设你写的最显著位第一:

240  170  204 
11110000 10101010 11001100 
111100 001010 101011 001100 
60  10  43  12 
+0

为什么'source [6]'当你只使用3个索引?另外,我会设置'unsigned char destinatio [4] = {0};'只是为了安全,但我不知道它的问题。 – 2009-12-08 23:09:11

+0

1)在早期版本中是6。我忘了改变它。 2)我将目标数组在下一行memset为零。 – 2009-12-08 23:14:28

0

我会考虑使用一个BitStream。它将允许您一次读取一个位。您可以直接将该位移位(使用< < n)。它的表现可能不如一次读取8位字节,但它肯定会是更清晰的代码。

0

这个联盟怎么样?

union _EIGHT_TO_SIX_ { 

    struct { 

     unsigned char by6Bit0 : 6; 
     unsigned char by6Bit1 : 6; 
     unsigned char by6Bit2 : 6; 
     unsigned char by6Bit3 : 6; 

    } x6; 

    struct { 

     unsigned char by8Bit0; 
     unsigned char by8Bit0; 
     unsigned char by8Bit0; 

    } x8; 
} 

设置by8Bitx将在by6Bitx自动填写~~~