2014-09-04 37 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