Как преобразовать 8-битные байты в 6-битные символы?
У меня есть конкретное требование преобразовать поток байтов в кодировку символов, которая бывает 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++). Спасибо!
2 ответов
Ну, каждые 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.
}
на всякий случай, если кто - то заинтересован-другой вариант, который извлекает 6-битные числа из потока, как только они появляются там. То есть, результаты могут быть получены, даже если в настоящее время менее 3-х байтов. Было бы полезно для unpadded потоков.
код сохраняет состояние аккумулятора 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;
}