Javascript:Base64编码/解码

更新于 2024-01-06

Base64编码/解码,依赖于Utf8Encoding【Javascript:UTF-8和Unicode互转】
Base64原理很简单:是把3个字节24位按照每组6位分成4个字节,而6位代表的最大数字范围为0-63,刚好26个字母大小写+10个数字,再加两个特殊字符就可以完全表示。

64 = 26 * 2 + 10 + 2

原数据长度不是3的倍数时候,用=号来补位。
由于是3字节变4字节,Base64编码后的数据长度会比原数据多1/3左右。

示例

var words = 'hello world!你好,世界!😁';
var base64 = Base64Encoding.encode(words);
console.log(base64)
console.log(Base64Encoding.decode(base64))

输出

aGVsbG8gd29ybGQh5L2g5aW977yM5LiW55WM77yB8J+YgQ==
hello world!你好,世界!😁

源代码

var Base64Encoding = (function(){

  var f = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+", "/", "="];

  var e = [];

  for (var i = 0; i < f.length; i++) {
    e[f[i].charCodeAt(0)] = i;
  }


  var base64_encode = function (t) {
    if (typeof t === 'string') t = Utf8Encoding.getBytes(t);
    if(t.length === 0) return '';

    var s = "";
    var g, h, j, p = 0,
      q = t.length,
      r = q - q % 3;

    while (p < r) {
      g = t[p++];
      h = t[p++];
      j = t[p++];
      s += f[g >> 2] + f[((g & 3) << 4) | (h >> 4)] + f[((h & 0xf) << 2) | (j >> 6)] + f[j & 0x3f]
    }
    if(q === r) return s;

    g = t[p++];
    s += f[g >> 2];

    if (q - r === 2) {
      h = t[p++];
      s += f[((g & 3) << 4) | (h >> 4)] + f[((h & 0xf) << 2)] + "="
      return s;
    }

    if (q - r === 1) s += f[((g & 3) << 4)] + "=="
    return s
  };


  var base64_decode = function (t, utf8) {
    t = t.replace(/\s/g, "");
    if (t === "") return utf8 !== false ? '' : []

    var s = [];
    var k, m, n, o = "";
    var p = 0,
      q = t.length,
      r = q;
    if (t.slice(-1) == "=") r = q - 4

    while (p < r) {
      k = e[t.charCodeAt(p++)];
      m = e[t.charCodeAt(p++)];
      n = e[t.charCodeAt(p++)];
      o = e[t.charCodeAt(p++)];
      s.push((k << 2) | (m >> 4), ((m & 0xf) << 4) | (n >> 2), ((n & 3) << 6) | o)
    }

    if (q != r) {
      k = e[t.charCodeAt(p++)];
      m = e[t.charCodeAt(p++)];
      if (t.slice(-2) == "==") {
        s.push((k << 2) | (m >> 4))
      } else {
        n = e[t.charCodeAt(p++)];
        s.push((k << 2) | (m >> 4), ((m & 0xf) << 4) | (n >> 2))
      }
    }
    if (utf8 !== false) return Utf8Encoding.getString(s)
    return s
  };

  return {
    encode: base64_encode,
    decode: base64_decode
  }
})();