【问题标题】:Guidance to understand Base64 encoding algorithm了解Base64编码算法的指导
【发布时间】:2014-09-04 22:47:21
【问题描述】:

我在网上找到了这个算法,但我在理解它的工作原理时遇到了一些麻烦。它将 Uint8Array 编码为 Base64。我想特别了解 cmets“将三个字节组合成一个整数”和“使用位掩码从三元组中提取 6 位段”下的部分。我理解那里使用的位移的概念,但无法理解这两个部分的目的是什么。

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

  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
}

【问题讨论】:

  • 关于 ASCII 编码的评论有点搞笑,因为 JavaScript 使用的是 UTF-16。

标签: javascript algorithm encoding base64 bit-shift


【解决方案1】:

第一步获取输入中的每组 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 个字节的倍数,那么最后会有一些特殊情况来处理。

【讨论】:

  • 这是对数字进行编码并通过基于文本的媒体发送数字的好方法,因为它为您提供了很好的压缩。通过您的回答,我能够理解它并设想如何解码它。对于那些需要了解位移的人来说,在程序员模式下使用 Windows 计算器和二进制文件会有很大帮助。谢谢巴尔玛。
  • 这正是 base64 编码的目的。大多数语言都有一个库函数为你执行编码和解码,你不需要自己做。
  • 是的,我发现已经实现了一些功能,但我需要针对数字进行优化,并且还需要与旧版浏览器兼容。我正在使用 JavaScript,它看起来像 btoa 等功能不受旧浏览器或非 HTML5 浏览器的支持。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多