2014-09-04 58 views
0

我在網絡上發現了這個算法,但我在理解它的工作原理時遇到了一些麻煩。它將Uint8Array編碼爲Base64。我想特別理解評論「將三個字節合併爲一個整數」和「使用位掩碼從三元組中提取6位段」下的部分。我理解這裏使用的位移的概念,但無法理解這兩部分中的目的。理解Base64編碼算法的指導

function base64ArrayBuffer(bytes) { 
    var base64 = '' 
    var encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/' 

    var byteLength = bytes.byteLength 
    var byteRemainder = byteLength % 3 
    var mainLength = byteLength - byteRemainder 

    var a, b, c, d 
    var chunk 

    // Main loop deals with bytes in chunks of 3 
    for (var i = 0; i < mainLength; i = i + 3) { 
    // Combine the three bytes into a single integer 
    chunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2] 

    // Use bitmasks to extract 6-bit segments from the triplet 
    a = (chunk & 16515072) >> 18 // 16515072 = (2^6 - 1) << 18 
    b = (chunk & 258048) >> 12 // 258048 = (2^6 - 1) << 12 
    c = (chunk & 4032)  >> 6 // 4032  = (2^6 - 1) << 6 
    d = chunk & 63    // 63  = 2^6 - 1 

    // Convert the raw binary segments to the appropriate ASCII encoding 
    base64 += encodings[a] + encodings[b] + encodings[c] + encodings[d] 
    } 

    // Deal with the remaining bytes and padding 
    if (byteRemainder == 1) { 
    chunk = bytes[mainLength] 

    a = (chunk & 252) >> 2 // 252 = (2^6 - 1) << 2 

    // Set the 4 least significant bits to zero 
    b = (chunk & 3) << 4 // 3 = 2^2 - 1 

    base64 += encodings[a] + encodings[b] + '==' 
    } else if (byteRemainder == 2) { 
    chunk = (bytes[mainLength] << 8) | bytes[mainLength + 1] 

    a = (chunk & 64512) >> 10 // 64512 = (2^6 - 1) << 10 
    b = (chunk & 1008) >> 4 // 1008 = (2^6 - 1) << 4 

    // Set the 2 least significant bits to zero 
    c = (chunk & 15) << 2 // 15 = 2^4 - 1 

    base64 += encodings[a] + encodings[b] + encodings[c] + '=' 
    } 

    return base64 
} 
+0

關於ASCII編碼的註釋很有趣,因爲JavaScript使用UTF-16。 – 2014-09-05 01:56:59

回答

0

第一步需要每個組的3個字節在輸入並將它們組合成一個24位的數。如果我們把它們x = bytes[i]y = bytes[i+1]z = bytes[i+2],它採用位移動和位或創建一個24位整數,其位是:

xxxxxxxxyyyyyyyyzzzzzzzz 

然後在6組拿到4中提取這些位數字。的abcd位對應是這樣的:

xxxxxxxxyyyyyyyyzzzzzzzz 
aaaaaabbbbbbccccccdddddd 

然後對於每個6位數字,它索引的encodings串得到相應的字符,並將它們連接到base64結果串。

最後有一些特殊情況需要處理輸入中的最後1或2個字節,如果它不是3個字節長的倍數。

+0

這是編碼數字並通過基於文本的媒體發送它的好方法,因爲它給你一個很好的壓縮。隨着你的回答,我能夠理解它,並設想如何解碼。對於那些需要了解位移的人來說,在Programmer模式和二進制文件中使用Windows計算器進行遊戲會有很大幫助。感謝Barmar。 – 2014-09-05 01:29:10

+0

這正是創建base64編碼的原因。大多數語言都有一個庫函數,可以爲你編碼和解碼,你不需要自己做。 – Barmar 2014-09-05 01:31:09

+0

是的,我發現有些東西是爲此而實現的,但我需要這樣做才能針對數字進行優化,並且與舊版瀏覽器兼容。我正在使用JavaScript,看起來像btoa等功能,不受舊版瀏覽器或非HTML5版本的支持。 – 2014-09-05 01:35:17