我有一个PHP脚本,可以将PNG图像编码为Base64字符串.
我想用JavaScript做同样的事情.我知道如何打开文件,但我不知道如何进行编码.我不习惯使用二进制数据.
您可以使用btoa()
和atob()
转换为base64编码.
关于这些功能接受/返回的评论似乎有些混乱,所以...
btoa()
接受一个"字符串",其中每个字符代表一个8位字节 - 如果你传递一个包含无法用8位表示的字符的字符串,它可能会中断.如果您实际将字符串视为字节数组,这不是问题,但如果您尝试执行其他操作,则必须先对其进行编码.
atob()
返回一个"字符串",其中每个字符代表一个8位字节 - 也就是说,它的值将在0
和之间0xff
.但这并不意味着它是ASCII -大概,如果您使用此功能在所有的,你还指望用二进制数据,而不是文字来工作.
如何使用Javascript和XMLHttpRequest加载二进制图像数据?
从这里:
/** * * 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(/\r\n/g,"\n"); 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; } }
此外,搜索"javascript base64 encoding"会转换很多其他选项,上面是第一个.
// 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!"
// 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>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 >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(/\r\n/g,"\n");var t="";for(var n=0;n 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 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!"
的jsfiddle
以下是在Node.js中将普通文本编码为base64的方法:
//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编码字符串的方法:
var b = new Buffer('SmF2YVNjcmlwdA==', 'base64') var s = b.toString();
使用dojox.encoding.base64编码字节数组:
var str = dojox.encoding.base64.encode(myByteArray);
要解码base64编码的字符串:
var bytes = dojox.encoding.base64.decode(str)
angular .module('myApp', ['base64']) .controller('myController', [ '$base64', '$scope', function($base64, $scope) { $scope.encoded = $base64.encode('a string'); $scope.decoded = $base64.decode('YSBzdHJpbmc='); }]);
Sunny的代码很棒,除非它在IE7中因为引用"this"而中断.通过用"Base64"替换这些引用来修复:
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(/\r\n/g,"\n"); 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; } }
您可以使用btoa
(to base-64)和atob
(from base-64).
对于IE 9及更低版本,请尝试使用jquery-base64插件:
$.base64.encode("this is a test"); $.base64.decode("dGhpcyBpcyBhIHRlc3Q=");
从接受的答案下面的评论(由SET和Stefan Steiger),这里是如何在不需要库的情况下将字符串编码/解码到base64的快速摘要.
str = "The quick brown fox jumps over the lazy dog"; b64 = btoa(unescape(encodeURIComponent(str))); str = decodeURIComponent(escape(window.atob(b64)));
(使用jQuery库,但不用于编码/解码)
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);
});
#btnDeConv{display:none;}
在两种实现方式中都存在一些错误_utf8_decode
.c1
并且c2
被指定为由于破碎使用的全局变量var
声明,并c3
在所有未初始化或声明.
它可以工作,但是这些变量将覆盖在此函数之外具有相同名称的任何现有变量.
这是一个不会这样做的版本:
// 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; }
我给了Sunny的回答,但是我想回馈一些我为自己的项目做出的改变,以防任何人发现它有用.基本上我只是稍微清理了原始代码,所以JSLint并没有那么多抱怨,而且我在评论中标记为私有的方法实际上是私有的.我还在我自己的项目中添加了两个方法,即decodeToHex
和encodeFromHex
.
代码:
var Base64 = (function() { "use strict"; var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; var _utf8_encode = function (string) { var utftext = "", c, n; string = string.replace(/\r\n/g,"\n"); 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编码的String URL友好,在JavaScript中你可以这样做:
// 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://jsfiddle.net/magikMaker/7bjaT/
我已经手工重写了这些编码和解码方法,除了十六进制之外的模块化格式,用于跨平台/浏览器兼容性以及真正的私有范围,并且使用btoa
并且atob
如果它们存在则由于速度而不是利用它自己的编码:
https://gist.github.com/Nijikokun/5192472
用法:
base64.encode(/* String */); base64.decode(/* String */); utf8.encode(/* String */); utf8.decode(/* String */);
这个问题及其答案向我指出了正确的方向.
特别是使用unicode atob和btoa不能使用"香草",而这些天一切都是unicode ..
直接来自Mozilla,有两个很好的功能用于此目的(内部使用unicode和html标签测试)
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('\n'); // "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=='); // "\n"
与使用自定义javascript函数的原始base64解码相比,这些函数将执行闪电,因为btoa和atob在解释器外执行.
如果你可以忽略旧的IE和旧的手机(如iphone 3?),这应该是一个很好的解决方案.
请注意,这不适用于原始Unicode字符串!请参阅此处的 Unicode部分.
编码语法
var encodedData = window.btoa(stringToEncode);
解码语法
var decodedData = window.atob(encodedData);
如果你需要编码HTML图像对象,你可以编写简单的函数,如:
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的图像:
function getBase64ImageById(id){ return getBase64Image(document.getElementById(id)); }
更多在这里
对于较新的浏览器,将Uint8Array编码为字符串,并将字符串解码为Uint8Array.
const base64 = { decode: s => Uint8Array.from(atob(s), c => c.charCodeAt(0)), encode: b => btoa(String.fromCharCode(...new Uint8Array(b))) };
对于Node.js,您可以使用以下命令将string,Buffer或Uint8Array编码为string,并从string,Buffer或Uint8Array解码为Buffer.
const base64 = { decode: s => Buffer.from(s, 'base64'), encode: b => Buffer.from(b).toString('base64') };
使用缩小的polyfill为我正在使用的window.atob
+进行贡献window.btoa
.
(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})})();
我宁愿使用CryptoJS的bas64编码/解码方法,CryptoJS是使用最佳实践和模式在JavaScript中实现的标准和安全加密算法的最流行的库.
这是@ user850789的AngularJS Factory版本之一:
'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(/\r\n/g, "\n"); 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; });
我需要将UTF-8字符串编码为我的项目的base64.这里的大部分答案在转换为UTF-8时似乎没有正确处理UTF-16代理对,所以为了完成起见,我将发布我的解决方案:
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(''); }
请注意,代码未经过全面测试.我测试了一些输入,包括类似的东西,strToUTF8Base64('????')
并与在线编码工具(https://www.base64encode.org/)的输出进行比较.
对于我的项目,我仍然需要支持IE7并使用大量输入进行编码。
根据Joe Dyndale提出的代码以及Marius的评论中的建议,可以通过使用数组而不是字符串构造结果来提高IE7的性能。
这是编码的示例:
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(""); };
好吧,如果您使用的是dojo,它为我们提供了直接编码或解码为base64的方法。
尝试这个:-
要使用dojox.encoding.base64编码字节数组:
var str = dojox.encoding.base64.encode(myByteArray);
要解码base64编码的字符串:
var bytes = dojox.encoding.base64.decode(str);
尽管还有更多工作要做,但是如果您需要高性能的本机解决方案,则可以使用一些HTML5函数。
如果您可以将数据放入Blob
,则可以使用FileReader.readAsDataURL()函数获取一个data://
URL,然后将其切掉以获取base64数据。
但是,您可能需要做进一步的处理才能对数据+
进行data://
url 解码,因为我不确定URL 是否对字符进行了转义,但这应该很简单。