javascript base64 encode decode 支持中文
* 字符编码
** 一定要知道数据的字符编码
** 使用utf-8字符编码存储数据
** 使用utf-8字符编码输出数据
* Crypto.js 支持中文
Base64编码说明
Base64编码要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之后在6位的前面补两个0,形成8位一个字节的形式。
如果剩下的字符不足3个字节,则用0填充,输出字符使用'=',因此编码后输出的文本末尾可能会出现1或2个'='。
为了保证所输出的编码位可读字符,Base64制定了一个编码表,以便进行统一转换。编码表的大小为2^6=64,这也是Base64名称的由来。
* 运算符优先级
* /
%
+ -
<< >>
== ===
| &
|| &&
// http://tool.oschina.net/encrypt?type=3 var CryptoJS = CryptoJS || function(h, o) { var f = {}; var j = f.lib = {}; var k = j.Base = function() { function a() {} return { extend: function(b) { a.prototype = this; var c = new a; b && c.mixIn(b); c.$super = this; return c }, create: function() { var a = this.extend(); a.init.apply(a, arguments); return a }, init: function() {}, mixIn: function(a) { for (var c in a) a.hasOwnProperty(c) && (this[c] = a[c]); a.hasOwnProperty("toString") && (this.toString = a.toString) }, clone: function() { return this.$super.extend(this) } } }(); var i = j.WordArray = k.extend({ init: function(a, b) { a = this.words = a || []; this.sigBytes = b != o ? b : 4 * a.length }, toString: function(a) { return (a || p).stringify(this) }, concat: function(a) { var b = this.words , c = a.words , d = this.sigBytes , a = a.sigBytes; this.clamp(); if (d % 4) for (var e = 0; e < a; e++) b[d + e >>> 2] |= (c[e >>> 2] >>> 24 - 8 * (e % 4) & 255) << 24 - 8 * ((d + e) % 4); else if (65535 < c.length) for (e = 0; e < a; e += 4) b[d + e >>> 2] = c[e >>> 2]; else b.push.apply(b, c); this.sigBytes += a; return this }, clamp: function() { var a = this.words , b = this.sigBytes; a[b >>> 2] &= 4294967295 << 32 - 8 * (b % 4); a.length = h.ceil(b / 4) }, clone: function() { var a = k.clone.call(this); a.words = this.words.slice(0); return a }, random: function(a) { for (var b = [], c = 0; c < a; c += 4) b.push(4294967296 * h.random() | 0); return i.create(b, a) } }), l = f.enc = {}, p = l.Hex = { stringify: function(a) { for (var b = a.words, a = a.sigBytes, c = [], d = 0; d < a; d++) { var e = b[d >>> 2] >>> 24 - 8 * (d % 4) & 255; c.push((e >>> 4).toString(16)); c.push((e & 15).toString(16)) } return c.join("") }, parse: function(a) { for (var b = a.length, c = [], d = 0; d < b; d += 2) c[d >>> 3] |= parseInt(a.substr(d, 2), 16) << 24 - 4 * (d % 8); return i.create(c, b / 2) } }, n = l.Latin1 = { stringify: function(a) { for (var b = a.words, a = a.sigBytes, c = [], d = 0; d < a; d++) c.push(String.fromCharCode(b[d >>> 2] >>> 24 - 8 * (d % 4) & 255)); return c.join("") }, parse: function(a) { for (var b = a.length, c = [], d = 0; d < b; d++) c[d >>> 2] |= (a.charCodeAt(d) & 255) << 24 - 8 * (d % 4); return i.create(c, b) } }, q = l.Utf8 = { stringify: function(a) { try { return decodeURIComponent(escape(n.stringify(a))) } catch (b) { throw Error("Malformed UTF-8 data"); } }, parse: function(a) { return n.parse(unescape(encodeURIComponent(a))) } }, m = j.BufferedBlockAlgorithm = k.extend({ reset: function() { this._data = i.create(); this._nDataBytes = 0 }, _append: function(a) { "string" == typeof a && (a = q.parse(a)); this._data.concat(a); this._nDataBytes += a.sigBytes }, _process: function(a) { var b = this._data , c = b.words , d = b.sigBytes , e = this.blockSize , f = d / (4 * e) , f = a ? h.ceil(f) : h.max((f | 0) - this._minBufferSize, 0) , a = f * e , d = h.min(4 * a, d); if (a) { for (var g = 0; g < a; g += e) this._doProcessBlock(c, g); g = c.splice(0, a); b.sigBytes -= d } return i.create(g, d) }, clone: function() { var a = k.clone.call(this); a._data = this._data.clone(); return a }, _minBufferSize: 0 }); j.Hasher = m.extend({ init: function() { this.reset() }, reset: function() { m.reset.call(this); this._doReset() }, update: function(a) { this._append(a); this._process(); return this }, finalize: function(a) { a && this._append(a); this._doFinalize(); return this._hash }, clone: function() { var a = m.clone.call(this); a._hash = this._hash.clone(); return a }, blockSize: 16, _createHelper: function(a) { return function(b, c) { return a.create(c).finalize(b) } }, _createHmacHelper: function(a) { return function(b, c) { return r.HMAC.create(a, c).finalize(b) } } }); var r = f.algo = {}; return f }(Math); (function() { var h = CryptoJS , i = h.lib.WordArray; h.enc.Base64 = { stringify: function(b) { var e = b.words , f = b.sigBytes , c = this._map; b.clamp(); for (var b = [], a = 0; a < f; a += 3) for (var d = (e[a >>> 2] >>> 24 - 8 * (a % 4) & 255) << 16 | (e[a + 1 >>> 2] >>> 24 - 8 * ((a + 1) % 4) & 255) << 8 | e[a + 2 >>> 2] >>> 24 - 8 * ((a + 2) % 4) & 255, g = 0; 4 > g && a + 0.75 * g < f; g++) b.push(c.charAt(d >>> 6 * (3 - g) & 63)); if (e = c.charAt(64)) for (; b.length % 4; ) b.push(e); return b.join("") }, parse: function(b) { var b = b.replace(/\s/g, "") , e = b.length , f = this._map , c = f.charAt(64); c && (c = b.indexOf(c), -1 != c && (e = c)); for (var c = [], a = 0, d = 0; d < e; d++) if (d % 4) { var g = f.indexOf(b.charAt(d - 1)) << 2 * (d % 4) , h = f.indexOf(b.charAt(d)) >>> 6 - 2 * (d % 4); c[a >>> 2] |= (g | h) << 24 - 8 * (a % 4); a++ } return i.create(c, a) }, _map: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" } } )();
test:
var str=CryptoJS.enc.Utf8.parse("这是一个测试用例"); var base64=CryptoJS.enc.Base64.stringify(str); console.log(base64); var words = CryptoJS.enc.Base64.parse(base64); console.log(words.toString(CryptoJS.enc.Utf8));
* 仅支持ascii版本
https://blog.csdn.net/chenxiaohua/article/details/4084602
(function() { var g_pCodes = (function() { var s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890+/=" var a = new Array(s.length); for (var i = 0, n = a.length; i < n; i++) { a[i] = s.charCodeAt(i); } return a; })(); // 256 var g_pMap = [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ]; var encode = function(s) { var pIn = s.split('').map(function(c) { return c.charCodeAt(0); }); var uInLen = s.length; var pIndex = 0; var len2 = Math.floor((uInLen+2)/3)<<2; var pOut = [], p = 0; var a, b, c; for (var i = 0, len = 3 * Math.floor(uInLen/3); i < len; i+=3) { a = pIn[i], b = pIn[i+1], c = pIn[i+2]; pOut.push( g_pCodes[ a >> 2 ] ); pOut.push( g_pCodes[((a & 3) << 4) + (b>>4)] ); pOut.push( g_pCodes[((b & 0xf) << 2) + (c>>6)] ); pOut.push( g_pCodes[ c & 0x3f]); } a = pIn[i], b = (i+1)<uInLen ? pIn[i+1]:0, c = 0; if (i < uInLen) { pOut.push( g_pCodes[a>>2]); pOut.push( g_pCodes[ ((a & 3)<<4) + (b >> 4)] ); pOut.push( ((i+1)<uInLen) ? g_pCodes[((b & 0xf) << 2)+(c>>6)] : '='.charCodeAt(0)); pOut.push( '='.charCodeAt(0) ); } return pOut.map(function(c) { return String.fromCharCode(c); }).join(''); }; var decode = function(s) { var x, y, z, t, c, g = 3; var strIn = s.split('').map(function(c) { return c.charCodeAt(0); }); var out = []; for (x = y = z = t = 0; x < strIn.length; x++) { c = g_pMap[strIn[x]]; if (c===255) {continue; } if (c===254) {c = 0, g--;} t = (t << 6) | c; if (++y === 4) { out.push( (t >> 16) & 255 ), z++; if (g > 1) { out.push((t >> 8) & 255), z++; } if (g > 2) { out.push(t & 255), z++; } y = t = 0; } } return out.map(function(c) { return String.fromCharCode(c); }).join(''); }; return base64 = { encode: encode, decode: decode } })(); // test @website: http://tool.oschina.net/encrypt?type=3 var s = "this is a example"; var enc = base64.encode(s); console.log(enc); console.log(base64.decode(enc));