我有一个数据流只能以8位字节寻址,我想将其解析为6位元素并将其存储到数组中。有没有最好的方法来做到这一点?如何解析字节可寻址数组中的n位元素
11110000 10101010 11001100
成
像
111100|001010|101011|001100
的阵列(可以具有零填充,只是需要寻址这样)
和数据是一个8位的阵列,其也是6位的倍数,并不是真正的无穷无尽
我有一个数据流只能以8位字节寻址,我想将其解析为6位元素并将其存储到数组中。有没有最好的方法来做到这一点?如何解析字节可寻址数组中的n位元素
11110000 10101010 11001100
成
像
111100|001010|101011|001100
的阵列(可以具有零填充,只是需要寻址这样)
和数据是一个8位的阵列,其也是6位的倍数,并不是真正的无穷无尽
依赖于一个字节多少位对您的具体架构。上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的模来代替分割。只需在循环中使用此函数来填充目标数组。
+1好的解决方案,比我的快得多。不过你可能想修正'error:'index'undeclared'。 – 2009-12-08 22:43:18
谢谢,修正。删除了一些不必要的括号,以便为注释提供更多地方;对于非C语言的人员,优先级应该用额外的空格来清楚。 – hirschhornsalz 2009-12-08 22:52:10
太好了,谢谢你比我的口才多 – stbtra 2009-12-09 01:18:12
你计数你的5位序列,读ea ch字节,根据您的计数器和期望的字位置(通过异或来自相邻字节字的字符)来移位位,并形成新的正确对齐的字节字,然后再处理。
我希望你不要指望代码...
如何使用一个结构是这样的:
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);
可以使用位摆弄做到这一点:
#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
为什么'source [6]'当你只使用3个索引?另外,我会设置'unsigned char destinatio [4] = {0};'只是为了安全,但我不知道它的问题。 – 2009-12-08 23:09:11
1)在早期版本中是6。我忘了改变它。 2)我将目标数组在下一行memset为零。 – 2009-12-08 23:14:28
我会考虑使用一个BitStream。它将允许您一次读取一个位。您可以直接将该位移位(使用< < n)。它的表现可能不如一次读取8位字节,但它肯定会是更清晰的代码。
这个联盟怎么样?
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自动填写~~~
这是5位数据元素的一个常数,层出不穷,或公知的结构,其重复? – qid 2009-12-08 22:19:42
也许有一些纠错冗余,总是假设最好;-) – hirschhornsalz 2009-12-08 22:50:49
这些字节写入最低有效位第一或最重要?换句话说,是(15,85,51)还是(240,170,204)? – 2009-12-08 23:05:20