2012-05-21 206 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

真不錯!謝謝 –