Base64的JavaScript实现(支持中文字符)

        Base64是一种基于64个可打印字符来表示二进制数据的表示方法。由于2的6次方等于64,所以每6个位元为一个单元,对应某个可打印字符。三个字节有24个位元,对应于4个Base64单元,即3个字节需要用4个可打印字符来表示。它可用来作为电子邮件的传输编码。在Base64中的可打印字符包括字母A-Z、a-z、数字0-9,这样共有62个字符,此外两个可打印符号在不同的系统中而不同。一些如uuencode的其他编码方法,和之后binhex的版本使用不同的64字符集来代表6个二进制数字,但是它们不叫Base64。Base64常用于在通常处理文本数据的场合,表示、传输、存储一些二进制数据。[转自维基百科]

        Base64编码将3个Byte共24Bit从高到低重新拆分成4部分每部分6Bit,分别为0x0~0x3f,对应字符为A~Z和a~z和0-9和+/,共64个。如果最后剩余1个Byte,则将其编码为2个6Bit的Base64编码(第二个Base64编码仅2Bit,需在其后面添加4Bit的0),再在末尾添加2个=字符;如果最后剩余2个Byte,则将其编码为3个6Bit的Base64编码(第三个Base64编码仅4Bit,需在其后面添加2Bit的0),再在末尾添加1个=字符。

       Base64解码的方法与编码相反,将4个Base64编码字符转换为对应的0x0~0x3f,共24Bit,然后重新拆分成3部分,每部分8Bit,即1Byte,若末尾有=字符,则按编码方法中描述的规则反向处理。

       Base64在谷歌、火狐浏览器都已经实现,调用方式很简单,window.atob是解码函数,把Base64编码转成字符串。window.btoa是编码函数,把字符串编码成Base64。不过谷歌和火狐浏览器实现的base64编码不支持中文,如果输入中文字符串会提示The string to be encoded contains characters outside of the Latin1 range。

        IE浏览器中没有内置Base64编码函数,不过网上有很多Base64的JavaScript实现。在众多Base64编码实现中,CryptoJS是最高效和全面的,CryptosJS是一个标准和安全的JavaScript加密算法库,实现了MD5、SHA、AES、DES、Base64等加密,其代码放在Google上托管,项目地址是https://code.google.com/p/crypto-js/。当然CryptoJS的Base64对中文也没有很好的支持。

       由于我的Base64编码有中文数据,所以自己实现了一个可以支持中文的方法。思路是在字符编码以前先用escape()转成非中文字符再进行编码,解码时用unescape()即可得到原来的字符。

(function(window){
	var base64 = {};
	base64.map = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
	base64.decode = function(s){
		s += '';
		var len = s.length;
		if((len === 0) || (len % 4 !== 0)){
			return s;
		}
		
		var pads = 0;
		if(s.charAt(len - 1) === base64.map[64]){
			pads++;
			if(s.charAt(len - 2) === base64.map[64]){
				pads++;
			}
			len -= 4;
		}
		
		var i, b, map = base64.map, x = [];
		for(i = 0; i < len; i += 4){
			b = (map.indexOf(s.charAt(i)) << 18) | (map.indexOf(s.charAt(i + 1)) << 12) | (map.indexOf(s.charAt(i + 2)) << 6) | map.indexOf(s.charAt(i + 3));
			x.push(String.fromCharCode(b >> 16, (b >> 8) & 0xff, b & 0xff));
		}
		
		switch(pads){
			case 1:
				b = (map.indexOf(s.charAt(i)) << 18) | (map.indexOf(s.charAt(i)) << 12) | (map.indexOf(s.charAt(i)) << 6);
				x.push(String.fromCharCode(b >> 16, (b >> 8) & 0xff));
				break;
			case 2:
				b = (map.indexOf(s.charAt(i)) << 18) | (map.indexOf(s.charAt(i)) << 12);
				x.push(String.fromCharCode(b >> 16));
				break;
		}
		return unescape(x.join(''));
	};
	
	base64.encode = function(s){
		if(!s){
			return;
		}
		
		s += '';		
		if(s.length === 0){
			return s;
		}
		s = escape(s);
		
		var i, b, x = [], map = base64.map, padchar = map[64];
		var len = s.length - s.length % 3;
		
		for(i = 0; i < len; i += 3){
			b = (s.charCodeAt(i) << 16) | (s.charCodeAt(i+1) << 8) | s.charCodeAt(i+2);
			x.push(map.charAt(b >> 18));
			x.push(map.charAt((b >> 12) & 0x3f));
			x.push(map.charAt((b >> 6) & 0x3f));
			x.push(map.charAt(b & 0x3f));
		}
		
		switch(s.length - len){
			case 1:
				b = s.charCodeAt(i) << 16;
				x.push(map.charAt(b >> 18) + map.charAt((b >> 12) & 0x3f) + padchar + padchar);
				break;
			case 2:
				b = (s.charCodeAt(i) << 16) | (s.charCodeAt(i + 1) << 8);
				x.push(map.charAt(b >> 18) + map.charAt((b >> 12) & 0x3f) + map.charAt((b >> 6) & 0x3f) + padchar);
				break;
		}
		return x.join('');
	};
	
	window.base64 = base64;
 })(window);


你可能感兴趣的:(Base64的JavaScript实现(支持中文字符))