How can you encode a string to Base64 in JavaScript?
我有一个PHP脚本,可以将PNG图像编码为base64字符串。
我想用JavaScript做同样的事情。我知道如何打开文件,但不知道如何进行编码。我不习惯使用二进制数据。
你可以使用
似乎是有一些进一步的评论是在接受有关这些功能/回报,所以……
在接受
btoa() a字符串每个字符代表的8位字节的字符串,如果你通过一个含字符可以代表8位,它可能会打破。这不是问题,如果你是作为一个字节数组字符串处理,但如果你想做什么,然后你有你的第一编码信息。返回"字符串"
atob() A在每个8位字节的字符代表,这是它的价值将0 和0xff 之间。这并不意味着它的ASCII presumably–如果你使用本函数在所有的期望,你的工作需要的文本和二进制数据。
所以:湖
- 我如何加载的二进制图像数据使用JavaScript和XMLHttpRequest?
从这里:
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 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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | /** * * Base64 encode / decode * http://www.webtoolkit.info/ * **/ var Base64 = { // private property _keyStr :"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", // public method for encoding encode : function (input) { var output =""; var chr1, chr2, chr3, enc1, enc2, enc3, enc4; var i = 0; input = Base64._utf8_encode(input); while (i < input.length) { chr1 = input.charCodeAt(i++); chr2 = input.charCodeAt(i++); chr3 = input.charCodeAt(i++); enc1 = chr1 >> 2; enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); enc4 = chr3 & 63; if (isNaN(chr2)) { enc3 = enc4 = 64; } else if (isNaN(chr3)) { enc4 = 64; } output = output + this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) + this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4); } return output; }, // public method for decoding decode : function (input) { var output =""; var chr1, chr2, chr3; var enc1, enc2, enc3, enc4; var i = 0; input = input.replace(/[^A-Za-z0-9\+\/\=]/g,""); while (i < input.length) { enc1 = this._keyStr.indexOf(input.charAt(i++)); enc2 = this._keyStr.indexOf(input.charAt(i++)); enc3 = this._keyStr.indexOf(input.charAt(i++)); enc4 = this._keyStr.indexOf(input.charAt(i++)); chr1 = (enc1 << 2) | (enc2 >> 4); chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); chr3 = ((enc3 & 3) << 6) | enc4; output = output + String.fromCharCode(chr1); if (enc3 != 64) { output = output + String.fromCharCode(chr2); } if (enc4 != 64) { output = output + String.fromCharCode(chr3); } } output = Base64._utf8_decode(output); return output; }, // private method for UTF-8 encoding _utf8_encode : function (string) { string = string.replace(/ /g," "); var utftext =""; for (var n = 0; n < string.length; n++) { var c = string.charCodeAt(n); if (c < 128) { utftext += String.fromCharCode(c); } else if((c > 127) && (c < 2048)) { utftext += String.fromCharCode((c >> 6) | 192); utftext += String.fromCharCode((c & 63) | 128); } else { utftext += String.fromCharCode((c >> 12) | 224); utftext += String.fromCharCode(((c >> 6) & 63) | 128); utftext += String.fromCharCode((c & 63) | 128); } } return utftext; }, // private method for UTF-8 decoding _utf8_decode : function (utftext) { var string =""; var i = 0; var c = c1 = c2 = 0; while ( i < utftext.length ) { c = utftext.charCodeAt(i); if (c < 128) { string += String.fromCharCode(c); i++; } else if((c > 191) && (c < 224)) { c2 = utftext.charCodeAt(i+1); string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); i += 2; } else { c2 = utftext.charCodeAt(i+1); c3 = utftext.charCodeAt(i+2); string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); i += 3; } } return string; } } |
因此,搜索"base64编码在JavaScript"原来很多其他选项,上面的是第一次。
Internet Explorer 10+
1 2 3 4 5 6 7 8 9 10 | // Define the string var string = 'Hello World!'; // Encode the String var encodedString = btoa(string); console.log(encodedString); // Outputs:"SGVsbG8gV29ybGQh" // Decode the String var decodedString = atob(encodedString); console.log(decodedString); // Outputs:"Hello World!" |
跨浏览器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | // Create Base64 Object var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(e){var t="";var n,r,i,s,o,u,a;var f=0;e=Base64._utf8_encode(e);while(f<e.length){n=e.charCodeAt(f++);r=e.charCodeAt(f++);i=e.charCodeAt(f++);s=n>>2;o=(n&3)<<4|r>>4;u=(r&15)<<2|i>>6;a=i&63;if(isNaN(r)){u=a=64}else if(isNaN(i)){a=64}t=t+this._keyStr.charAt(s)+this._keyStr.charAt(o)+this._keyStr.charAt(u)+this._keyStr.charAt(a)}return t},decode:function(e){var t="";var n,r,i;var s,o,u,a;var f=0;e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(f<e.length){s=this._keyStr.indexOf(e.charAt(f++));o=this._keyStr.indexOf(e.charAt(f++));u=this._keyStr.indexOf(e.charAt(f++));a=this._keyStr.indexOf(e.charAt(f++));n=s<<2|o>>4;r=(o&15)<<4|u>>2;i=(u&3)<<6|a;t=t+String.fromCharCode(n);if(u!=64){t=t+String.fromCharCode(r)}if(a!=64){t=t+String.fromCharCode(i)}}t=Base64._utf8_decode(t);return t},_utf8_encode:function(e){e=e.replace(/ /g," ");var t="";for(var n=0;n<e.length;n++){var r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r)}else if(r>127&&r<2048){t+=String.fromCharCode(r>>6|192);t+=String.fromCharCode(r&63|128)}else{t+=String.fromCharCode(r>>12|224);t+=String.fromCharCode(r>>6&63|128);t+=String.fromCharCode(r&63|128)}}return t},_utf8_decode:function(e){var t="";var n=0;var r=c1=c2=0;while(n<e.length){r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r);n++}else if(r>191&&r<224){c2=e.charCodeAt(n+1);t+=String.fromCharCode((r&31)<<6|c2&63);n+=2}else{c2=e.charCodeAt(n+1);c3=e.charCodeAt(n+2);t+=String.fromCharCode((r&15)<<12|(c2&63)<<6|c3&63);n+=3}}return t}} // Define the string var string = 'Hello World!'; // Encode the String var encodedString = Base64.encode(string); console.log(encodedString); // Outputs:"SGVsbG8gV29ybGQh" // Decode the String var decodedString = Base64.decode(encodedString); console.log(decodedString); // Outputs:"Hello World!" |
杰西德
和Node.js下面是在node.js中将普通文本编码为base64的方法:
1 2 3 4 5 6 | //Buffer() requires a number, array or string as the first parameter, and an optional encoding type as the second parameter. // Default is utf8, possible encoding types are ascii, utf8, ucs2, base64, binary, and hex var b = new Buffer('JavaScript'); // If we don't use toString(), JavaScript assumes we want to convert the object to utf8. // We can make it convert to other formats by passing the encoding type to toString(). var s = b.toString('base64'); |
下面是您如何解码base64编码的字符串:
1 2 | var b = new Buffer('SmF2YVNjcmlwdA==', 'base64') var s = b.toString(); |
和Dojo.js
要使用dojox.encoding.base64对字节数组进行编码:
1 | var str = dojox.encoding.base64.encode(myByteArray); |
要解码base64编码的字符串:
1 | var bytes = dojox.encoding.base64.decode(str) |
鲍尔安装角基64
1 2 3 4 5 6 7 8 9 10 11 12 | <script src="bower_components/angular-base64/angular-base64.js"> angular .module('myApp', ['base64']) .controller('myController', [ '$base64', '$scope', function($base64, $scope) { $scope.encoded = $base64.encode('a string'); $scope.decoded = $base64.decode('YSBzdHJpbmc='); }]); |
阳光明媚的代码是伟大的除了它打破在IE7的,因为引用的"本"。有一个固定的搜索引用"base64":
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 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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | var Base64 = { // private property _keyStr :"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", // public method for encoding encode : function (input) { var output =""; var chr1, chr2, chr3, enc1, enc2, enc3, enc4; var i = 0; input = Base64._utf8_encode(input); while (i < input.length) { chr1 = input.charCodeAt(i++); chr2 = input.charCodeAt(i++); chr3 = input.charCodeAt(i++); enc1 = chr1 >> 2; enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); enc4 = chr3 & 63; if (isNaN(chr2)) { enc3 = enc4 = 64; } else if (isNaN(chr3)) { enc4 = 64; } output = output + Base64._keyStr.charAt(enc1) + Base64._keyStr.charAt(enc2) + Base64._keyStr.charAt(enc3) + Base64._keyStr.charAt(enc4); } return output; }, // public method for decoding decode : function (input) { var output =""; var chr1, chr2, chr3; var enc1, enc2, enc3, enc4; var i = 0; input = input.replace(/[^A-Za-z0-9\+\/\=]/g,""); while (i < input.length) { enc1 = Base64._keyStr.indexOf(input.charAt(i++)); enc2 = Base64._keyStr.indexOf(input.charAt(i++)); enc3 = Base64._keyStr.indexOf(input.charAt(i++)); enc4 = Base64._keyStr.indexOf(input.charAt(i++)); chr1 = (enc1 << 2) | (enc2 >> 4); chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); chr3 = ((enc3 & 3) << 6) | enc4; output = output + String.fromCharCode(chr1); if (enc3 != 64) { output = output + String.fromCharCode(chr2); } if (enc4 != 64) { output = output + String.fromCharCode(chr3); } } output = Base64._utf8_decode(output); return output; }, // private method for UTF-8 encoding _utf8_encode : function (string) { string = string.replace(/ /g," "); var utftext =""; for (var n = 0; n < string.length; n++) { var c = string.charCodeAt(n); if (c < 128) { utftext += String.fromCharCode(c); } else if((c > 127) && (c < 2048)) { utftext += String.fromCharCode((c >> 6) | 192); utftext += String.fromCharCode((c & 63) | 128); } else { utftext += String.fromCharCode((c >> 12) | 224); utftext += String.fromCharCode(((c >> 6) & 63) | 128); utftext += String.fromCharCode((c & 63) | 128); } } return utftext; }, // private method for UTF-8 decoding _utf8_decode : function (utftext) { var string =""; var i = 0; var c = c1 = c2 = 0; while ( i < utftext.length ) { c = utftext.charCodeAt(i); if (c < 128) { string += String.fromCharCode(c); i++; } else if((c > 191) && (c < 224)) { c2 = utftext.charCodeAt(i+1); string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); i += 2; } else { c2 = utftext.charCodeAt(i+1); c3 = utftext.charCodeAt(i+2); string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); i += 3; } } return string; } } |
你可以使用
for IE 9和下面的jQuery插件,try:base64
1 2 | $.base64.encode("this is a test"); $.base64.decode("dGhpcyBpcyBhIHRlc3Q="); |
有一个错误在几
它提出,但任何一个想要覆盖现有的变量相同的名称,这个功能。
这是一个版本,不会这样做:
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 26 27 28 29 | // private method for UTF-8 decoding _utf8_decode : function (utftext) { var string =""; var i = 0; var c = 0, c1 = 0, c2 = 0; while ( i < utftext.length ) { c = utftext.charCodeAt(i); if (c < 128) { string += String.fromCharCode(c); i++; } else if((c > 191) && (c < 224)) { c1 = utftext.charCodeAt(i+1); string += String.fromCharCode(((c & 31) << 6) | (c1 & 63)); i += 2; } else { c1 = utftext.charCodeAt(i+1); c2 = utftext.charCodeAt(i+2); string += String.fromCharCode(((c & 15) << 12) | ((c1 & 63) << 6) | (c2 & 63)); i += 3; } } return string; } |
根据接受答案下面的注释(由set和stefan steiger编写),这里简要介绍了如何在不需要库的情况下将字符串编码/解码到base64或从base64解码。
1 2 3 | str ="The quick brown fox jumps over the lazy dog"; b64 = btoa(unescape(encodeURIComponent(str))); str = decodeURIComponent(escape(window.atob(b64))); |
演示
(使用jquery库,但不用于编码/解码)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | str ="The quick brown fox jumps over the lazy dog"; $('input').val(str); $('#btnConv').click(function(){ var txt = $('input').val(); var b64 = btoa(unescape(encodeURIComponent(txt))); $('input').val(b64); $('#btnDeConv').show(); }); $('#btnDeConv').click(function(){ var b64 = $('input').val(); var txt = decodeURIComponent(escape(window.atob(b64))); $('input').val(txt); }); |
1 | #btnDeConv{display:none;} |
1 2 3 4 5 | <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"> <input type="text" /> <button id="btnConv">Convert</button> <button id="btnDeConv">DeConvert</button> |
i + 1)阳光明媚的回答,但我想以一个我回自己的变化制造项目案例的人应该找到有用的。基本上我只是去上原代码一点这样JSLint不抱怨太多的AS,AS和一私人在制造方法标记的评论是私人的。所以我需要添加一个方法在我自己的项目,即
的代码:
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 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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | var Base64 = (function() { "use strict"; var _keyStr ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; var _utf8_encode = function (string) { var utftext ="", c, n; string = string.replace(/ /g," "); for (n = 0; n < string.length; n++) { c = string.charCodeAt(n); if (c < 128) { utftext += String.fromCharCode(c); } else if((c > 127) && (c < 2048)) { utftext += String.fromCharCode((c >> 6) | 192); utftext += String.fromCharCode((c & 63) | 128); } else { utftext += String.fromCharCode((c >> 12) | 224); utftext += String.fromCharCode(((c >> 6) & 63) | 128); utftext += String.fromCharCode((c & 63) | 128); } } return utftext; }; var _utf8_decode = function (utftext) { var string ="", i = 0, c = 0, c1 = 0, c2 = 0; while ( i < utftext.length ) { c = utftext.charCodeAt(i); if (c < 128) { string += String.fromCharCode(c); i++; } else if((c > 191) && (c < 224)) { c1 = utftext.charCodeAt(i+1); string += String.fromCharCode(((c & 31) << 6) | (c1 & 63)); i += 2; } else { c1 = utftext.charCodeAt(i+1); c2 = utftext.charCodeAt(i+2); string += String.fromCharCode(((c & 15) << 12) | ((c1 & 63) << 6) | (c2 & 63)); i += 3; } } return string; }; var _hexEncode = function(input) { var output = '', i; for(i = 0; i < input.length; i++) { output += input.charCodeAt(i).toString(16); } return output; }; var _hexDecode = function(input) { var output = '', i; if(input.length % 2 > 0) { input = '0' + input; } for(i = 0; i < input.length; i = i + 2) { output += String.fromCharCode(parseInt(input.charAt(i) + input.charAt(i + 1), 16)); } return output; }; var encode = function (input) { var output ="", chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0; input = _utf8_encode(input); while (i < input.length) { chr1 = input.charCodeAt(i++); chr2 = input.charCodeAt(i++); chr3 = input.charCodeAt(i++); enc1 = chr1 >> 2; enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); enc4 = chr3 & 63; if (isNaN(chr2)) { enc3 = enc4 = 64; } else if (isNaN(chr3)) { enc4 = 64; } output += _keyStr.charAt(enc1); output += _keyStr.charAt(enc2); output += _keyStr.charAt(enc3); output += _keyStr.charAt(enc4); } return output; }; var decode = function (input) { var output ="", chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0; input = input.replace(/[^A-Za-z0-9\+\/\=]/g,""); while (i < input.length) { enc1 = _keyStr.indexOf(input.charAt(i++)); enc2 = _keyStr.indexOf(input.charAt(i++)); enc3 = _keyStr.indexOf(input.charAt(i++)); enc4 = _keyStr.indexOf(input.charAt(i++)); chr1 = (enc1 << 2) | (enc2 >> 4); chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); chr3 = ((enc3 & 3) << 6) | enc4; output += String.fromCharCode(chr1); if (enc3 !== 64) { output += String.fromCharCode(chr2); } if (enc4 !== 64) { output += String.fromCharCode(chr3); } } return _utf8_decode(output); }; var decodeToHex = function(input) { return _hexEncode(decode(input)); }; var encodeFromHex = function(input) { return encode(_hexDecode(input)); }; return { 'encode': encode, 'decode': decode, 'decodeToHex': decodeToHex, 'encodeFromHex': encodeFromHex }; }()); |
Base64编码的字符串的URL,使A在JavaScript友好,你可以做这样的东西:
1 2 3 4 5 6 7 8 9 | // if this is your Base64 encoded string var str = 'VGhpcyBpcyBhbiBhd2Vzb21lIHNjcmlwdA=='; // make URL friendly: str = str.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=+$/, ''); // reverse to original encoding str = (str + '===').slice(0, str.length + (str.length % 4)); str = str.replace(/-/g, '+').replace(/_/g, '/'); |
所以这个湖小提琴:http://///7bjat magikmaker jsfiddle.net
这个问题和答案为我指明了正确的方向。尤其是使用Unicode ATOB和BTOA时,不能使用"香草",现在一切都是Unicode。
直接从Mozilla,两个很好的函数用于此目的(在内部用unicode和html标签测试)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | function b64EncodeUnicode(str) { return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) { return String.fromCharCode('0x' + p1); })); } b64EncodeUnicode('? à la mode'); //"4pyTIMOgIGxhIG1vZGU=" b64EncodeUnicode(' '); //"Cg==" function b64DecodeUnicode(str) { return decodeURIComponent(Array.prototype.map.call(atob(str), function(c) { return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); }).join('')); } b64DecodeUnicode('4pyTIMOgIGxhIG1vZGU='); //"? à la mode" b64DecodeUnicode('Cg=='); //" " |
与使用自定义javascript函数的RAW BASE64解码相比,这些函数将以闪电般的速度执行,因为BTOA和ATOB是在解释器外执行的。
如果你能忽略旧的IE和旧的手机(比如iPhone3?)这应该是一个很好的解决方案。
我写的论文在重新编码和解码方法,与异常的一个模块化的格式是十六进制形式的一个跨平台的兼容性和与真实/浏览器的私人使用范围和
http:/ / / / 5192472 gist.github.com nijikokun
用法:
1 2 3 4 5 | base64.encode(/* String */); base64.decode(/* String */); utf8.encode(/* String */); utf8.decode(/* String */); |
请注意,这不是适合原始的Unicode字符串。湖在Unicode的截面。
语法和编码
为解码语法
如果你需要HTML编码图像对象你可以写简单的功能类:
1 2 3 4 5 6 7 8 9 10 11 12 | function getBase64Image(img) { var canvas = document.createElement("canvas"); canvas.width = img.width; canvas.height = img.height; var ctx = canvas.getContext("2d"); ctx.drawImage(img, 0, 0); var dataURL = canvas.toDataURL("image/png"); // escape data:image prefix return dataURL.replace(/^data:image\/(png|jpg);base64,/,""); // or just return dataURL // return dataURL } |
通过把图像ID:base64
1 2 3 | function getBase64ImageById(id){ return getBase64Image(document.getElementById(id)); } |
更多在这里
一个polyfill被缩小为
1 | (function(){function t(t){this.message=t}var e="undefined"!=typeof exports?exports:this,r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";t.prototype=Error(),t.prototype.name="InvalidCharacterError",e.btoa||(e.btoa=function(e){for(var o,n,a=0,i=r,c="";e.charAt(0|a)||(i="=",a%1);c+=i.charAt(63&o>>8-8*(a%1))){if(n=e.charCodeAt(a+=.75),n>255)throw new t("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.");o=o<<8|n}return c}),e.atob||(e.atob=function(e){if(e=e.replace(/=+$/,""),1==e.length%4)throw new t("'atob' failed: The string to be decoded is not correctly encoded.");for(var o,n,a=0,i=0,c="";n=e.charAt(i++);~n&&(o=a%4?64*o+n:n,a++%4)?c+=String.fromCharCode(255&o>>(6&-2*a)):0)n=r.indexOf(n);return c})})(); |
我宁愿使用"编码/解码方法和bas64 cryptojs,最流行的标准和安全的加密算法库,用于实现在JavaScript中使用的最佳实践和模式。
我的一个项目需要将utf-8字符串编码为base64。这里的大多数答案在转换为UTF-8时似乎无法正确处理UTF-16代理项对,因此,为了完整起见,我将发布我的解决方案:
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 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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | function strToUTF8Base64(str) { function decodeSurrogatePair(hi, lo) { var resultChar = 0x010000; resultChar += lo - 0xDC00; resultChar += (hi - 0xD800) << 10; return resultChar; } var bytes = [0, 0, 0]; var byteIndex = 0; var result = []; function output(s) { result.push(s); } function emitBase64() { var digits = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + 'abcdefghijklmnopqrstuvwxyz' + '0123456789+/'; function toDigit(value) { return digits[value]; } // --Byte 0-- --Byte 1-- --Byte 2-- // 1111 1122 2222 3333 3344 4444 var d1 = toDigit(bytes[0] >> 2); var d2 = toDigit( ((bytes[0] & 0x03) << 4) | (bytes[1] >> 4)); var d3 = toDigit( ((bytes[1] & 0x0F) << 2) | (bytes[2] >> 6)); var d4 = toDigit( bytes[2] & 0x3F); if (byteIndex === 1) { output(d1 + d2 + '=='); } else if (byteIndex === 2) { output(d1 + d2 + d3 + '='); } else { output(d1 + d2 + d3 + d4); } } function emit(chr) { bytes[byteIndex++] = chr; if (byteIndex == 3) { emitBase64(); bytes[0] = 0; bytes[1] = 0; bytes[2] = 0; byteIndex = 0; } } function emitLast() { if (byteIndex > 0) { emitBase64(); } } // Converts the string to UTF8: var i, chr; var hi, lo; for (i = 0; i < str.length; i++) { chr = str.charCodeAt(i); // Test and decode surrogate pairs in the string if (chr >= 0xD800 && chr <= 0xDBFF) { hi = chr; lo = str.charCodeAt(i + 1); if (lo >= 0xDC00 && lo <= 0xDFFF) { chr = decodeSurrogatePair(hi, lo); i++; } } // Encode the character as UTF-8. if (chr < 0x80) { emit(chr); } else if (chr < 0x0800) { emit((chr >> 6) | 0xC0); emit(((chr >> 0) & 0x3F) | 0x80); } else if (chr < 0x10000) { emit((chr >> 12) | 0xE0); emit(((chr >> 6) & 0x3F) | 0x80); emit(((chr >> 0) & 0x3F) | 0x80); } else if (chr < 0x110000) { emit((chr >> 18) | 0xF0); emit(((chr >> 12) & 0x3F) | 0x80); emit(((chr >> 6) & 0x3F) | 0x80); emit(((chr >> 0) & 0x3F) | 0x80); } } emitLast(); return result.join(''); } |
请注意,代码没有经过彻底测试。我测试了一些输入,包括
对于较新的浏览器,将uint8array编码为字符串,并将字符串解码为uint8array。
1 2 3 4 | const base64 = { decode: s => Uint8Array.from(atob(s), c => c.charCodeAt(0)), encode: b => btoa(String.fromCharCode(...new Uint8Array(b))) }; |
对于node.js,可以使用以下方法将字符串、缓冲区或uint8array编码为字符串,并从字符串、缓冲区或uint8array解码为缓冲区。
1 2 3 4 | const base64 = { decode: s => Buffer.from(s, 'base64'), encode: b => Buffer.from(b).toString('base64') }; |
这里是一个angularjs厂"的一user850789版本:
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 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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | 'use strict'; var ProjectNameBase64Factory = angular.module('project_name.factories.base64', []); ProjectNameBase64Factory.factory('Base64', function () { var Base64 = { // private property _keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", // public method for encoding encode: function (input) { var output =""; var chr1, chr2, chr3, enc1, enc2, enc3, enc4; var i = 0; input = Base64._utf8_encode(input); while (i < input.length) { chr1 = input.charCodeAt(i++); chr2 = input.charCodeAt(i++); chr3 = input.charCodeAt(i++); enc1 = chr1 >> 2; enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); enc4 = chr3 & 63; if (isNaN(chr2)) { enc3 = enc4 = 64; } else if (isNaN(chr3)) { enc4 = 64; } output = output + Base64._keyStr.charAt(enc1) + Base64._keyStr.charAt(enc2) + Base64._keyStr.charAt(enc3) + Base64._keyStr.charAt(enc4); } return output; }, // public method for decoding decode: function (input) { var output =""; var chr1, chr2, chr3; var enc1, enc2, enc3, enc4; var i = 0; input = input.replace(/[^A-Za-z0-9\+\/\=]/g,""); while (i < input.length) { enc1 = Base64._keyStr.indexOf(input.charAt(i++)); enc2 = Base64._keyStr.indexOf(input.charAt(i++)); enc3 = Base64._keyStr.indexOf(input.charAt(i++)); enc4 = Base64._keyStr.indexOf(input.charAt(i++)); chr1 = (enc1 << 2) | (enc2 >> 4); chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); chr3 = ((enc3 & 3) << 6) | enc4; output = output + String.fromCharCode(chr1); if (enc3 != 64) { output = output + String.fromCharCode(chr2); } if (enc4 != 64) { output = output + String.fromCharCode(chr3); } } output = Base64._utf8_decode(output); return output; }, // private method for UTF-8 encoding _utf8_encode: function (string) { string = string.replace(/ /g," "); var utftext =""; for (var n = 0; n < string.length; n++) { var c = string.charCodeAt(n); if (c < 128) { utftext += String.fromCharCode(c); } else if ((c > 127) && (c < 2048)) { utftext += String.fromCharCode((c >> 6) | 192); utftext += String.fromCharCode((c & 63) | 128); } else { utftext += String.fromCharCode((c >> 12) | 224); utftext += String.fromCharCode(((c >> 6) & 63) | 128); utftext += String.fromCharCode((c & 63) | 128); } } return utftext; }, // private method for UTF-8 decoding _utf8_decode: function (utftext) { var string =""; var i = 0; var c = 0, c2 = 0, c3 = 0; while (i < utftext.length) { c = utftext.charCodeAt(i); if (c < 128) { string += String.fromCharCode(c); i++; } else if ((c > 191) && (c < 224)) { c2 = utftext.charCodeAt(i + 1); string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); i += 2; } else { c2 = utftext.charCodeAt(i + 1); c3 = utftext.charCodeAt(i + 2); string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); i += 3; } } return string; } }; return Base64; }); |
好的,如果你使用的是直接的道场,它给美国的方式来编码或解码成base64。
试试这个:
一个dojox.encoding.base64字节编码阵列的使用:
1 | var str = dojox.encoding.base64.encode(myByteArray); |
Base64编码解码一个字符串:
1 | var bytes = dojox.encoding.base64.decode(str); |
如果您想要一个高性能的本机解决方案,您可以使用一些HTML5函数。
如果您可以将数据放入
但是,您可能需要做进一步的处理来对数据进行urlcode,因为我不确定
我还需要为我的项目和支持IE7与编码输入到大。
提出了基于代码的建议和评论。在乔dyndale由马吕斯,它是可能的性能改善的结果与IE7的构建一个数组而不是一个字符串。
这是用于编码的例子:
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 26 27 28 29 30 31 | var encode = function (input) { var output = [], chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0; input = _utf8_encode(input); while (i < input.length) { chr1 = input.charCodeAt(i++); chr2 = input.charCodeAt(i++); chr3 = input.charCodeAt(i++); enc1 = chr1 >> 2; enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); enc4 = chr3 & 63; if (isNaN(chr2)) { enc3 = enc4 = 64; } else if (isNaN(chr3)) { enc4 = 64; } output.push(_keyStr.charAt(enc1)); output.push(_keyStr.charAt(enc2)); output.push(_keyStr.charAt(enc3)); output.push(_keyStr.charAt(enc4)); } return output.join(""); }; |
下面是
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 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 52 | <!DOCTYPE html> <html> <head> <style> textarea{ width:30%; height:100px; } </style> // encode string to base64 function encode() { var txt = document.getElementById("txt1").value; var result = btoa(txt); document.getElementById("txt2").value = result; } // decode base64 back to original string function decode() { var txt = document.getElementById("txt3").value; var result = atob(txt); document.getElementById("txt4").value = result; } </head> <body> <textarea id="txt1">Some text to decode </textarea> <input type="button" id="btnencode" value="Encode" onClick="encode()"/> <textarea id="txt2"> </textarea> <br/> <textarea id="txt3">U29tZSB0ZXh0IHRvIGRlY29kZQ== </textarea> <input type="button" id="btndecode" value="Decode" onClick="decode()"/> <textarea id="txt4"> </textarea> </body> </html> |
你可以使用
1 2 | const encoded = window.btoa('Alireza Dezfoolian'); // encode a string const decoded = window.atob(encoded); // decode the string |
也许用MDN的方式做你最好的工作…同时接受Unicode…使用这两个简单的函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // ucs-2 string to base64 encoded ascii function utoa(str) { return window.btoa(unescape(encodeURIComponent(str))); } // base64 encoded ascii to ucs-2 string function atou(str) { return decodeURIComponent(escape(window.atob(str))); } // Usage: utoa('? à la mode'); // 4pyTIMOgIGxhIG1vZGU= atou('4pyTIMOgIGxhIG1vZGU='); //"? à la mode" utoa('I \u2661 Unicode!'); // SSDimaEgVW5pY29kZSE= atou('SSDimaEgVW5pY29kZSE='); //"I ? Unicode!" |