2012-05-21 184 views
7

我有一个具体的要求,将字节流转换为恰好是每个字符6位的字符编码。如何将8位字节转换为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++)。谢谢!

+0

有人认为要问相反的问题吗? – Marine1

回答

6

那么,每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. 
} 
+0

好东西,谢谢。如果您想知道,请回答您的问题......它总是被填充。 –

3

以防万一,如果有人有兴趣 - 即只要他们出现在那里从流中提取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; 
} 
+0

真不错!谢谢 –