9

バイトのストリームを、たまたま1文字あたり6ビットの文字エンコードに変換するという特定の要件があります。

Here's an example:

Input: 0x50 0x11 0xa0

Character Table:

010100 T
000001 A
000110 F
100000 SPACE


Output: "TAF "

Logically I can understand how this works:

Taking 0x50 0x11 0xa0 and showing as binary:

01010000 00010001 10100000

Which is "TAF ".

これをプログラムで行うための最良の方法は何ですか(擬似コードまたはc ++)。ありがとうございました!

4

2 に答える 2

7

つまり、3 バイトごとに 4 文字になります。そのため、1 つには、入力が 3 バイトの倍数でない場合にどうするかを考える必要があります。(base64 のような、ある種のパディングはありますか?)

次に、おそらく3バイトごとに順番に取得します。C# では、C の疑似コードに十分近い :)

for (int i = 0; i < array.Length; i += 3)
{
    // Top 6 bits of byte i
    int value1 = array[i] >> 2;
    // Bottom 2 bits of byte i, top 4 bits of byte i+1
    int value2 = ((array[i] & 0x3) << 4) | (array[i + 1] >> 4);
    // Bottom 4 bits of byte i+1, top 2 bits of byte i+2
    int value3 = ((array[i + 1] & 0xf) << 2) | (array[i + 2] >> 6);
    // Bottom 6 bits of byte i+2
    int value4 = array[i + 2] & 0x3f;

    // Now use value1...value4, e.g. putting them into a char array.
    // You'll need to decode from the 6-bit number (0-63) to the character.
}
于 2012-05-21T19:20:43.620 に答える
4

誰かが興味を持った場合に備えて、ストリームから6ビットの数値が表示されるとすぐに抽出する別のバリ​​アント。つまり、現在3バイト未満が読み取られている場合でも結果を取得できます。パディングされていないストリームに役立ちます。

このコードは、アキュムレータの状態をa変数nに保存します。この変数には、前回の読み取りからアキュムレータに残っているビット数が格納されます。

int n = 0;
unsigned char a = 0;
unsigned char b = 0;
while (read_byte(&byte)) {
    // save (6-n) most significant bits of input byte to proper position
    // in accumulator
    a |= (b >> (n + 2)) & (077 >> n);
    store_6bit(a);
    a = 0;
    // save remaining least significant bits of input byte to proper
    // position in accumulator
    a |= (b << (4 - n)) & ((077 << (4 - n)) & 077);
    if (n == 4) {
        store_6bit(a);
        a = 0;
    }
    n = (n + 2) % 6;
}
于 2012-05-21T19:56:36.000 に答える