바이트 주소 지정 가능 배열에서 n비트 요소를 어떻게 구문 분석합니까?

StackOverflow https://stackoverflow.com/questions/1870237

  •  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 ~~~가 자동으로 채워집니다

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top