바이트 주소 지정 가능 배열에서 n비트 요소를 어떻게 구문 분석합니까?
-
18-09-2019 - |
문제
8비트 바이트로만 주소를 지정할 수 있는 데이터 스트림이 있는데, 이를 6비트 요소로 구문 분석하여 배열에 저장하고 싶습니다.이를 수행하는 가장 잘 알려진 방법이 있습니까?
11110000 10101010 11001100
~ 안으로
다음과 같은 배열
111100|001010|101011|001100
(패딩이 0일 수 있으며 이 방법으로 주소를 지정할 수 있어야 함)
데이터는 6비트의 배수인 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-th 6 비트 그룹입니다. 괜찮은 컴파일러는 분할을 교대로 대체 할 것입니다. 이 기능을 루프에서 사용하여 대상 배열을 채우십시오.
다른 팁
5 비트 시퀀스를 계산하고 각 바이트를 읽고 카운터와 예상되는 단어 위치 (인접 바이트 단어의 xor-ing 조각으로)를 기준으로 비트를 바꾸고, 그 다음 처리 할 새로 올바르게 정렬 된 바이트 단어를 형성합니다.
코드를 기대하지 않기를 바랍니다 ...
비트 피들링을 사용하여 할 수 있습니다.
#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
이것은 5 개부터 작동하기 시작합니다 최소 중요한 비트.
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
이와 같은 구조물을 사용하는 것은 어떻습니까 :
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
5 비트 덩어리를 얻으려면 8 바이트 (40 비트 = 8 그룹, 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);
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를 설정하면 6bitx ~~~가 자동으로 채워집니다