搜索:
首页 >> JavaScript >> Js高级编程 >> JavaScript 中的 Base64 编码(一):Encode

JavaScript 中的 Base64 编码(一):Encode

2010-7-23 asp之家 投递文章

除了IE浏览器,其他所有主流的浏览器均支持原生的 Base64 编码:

btoa(text) – base64 encodes text. atob(text) – base64 decodes text.

而对于 IE 我们可以根据已知的 Base64 编码原理进行编写:

Base64 编码将每三个 8Bit 的字节(注:由于要求输入的字符为 8Bit 字节,故范围应该在 ASCII 字符范围内,即:u0000-u00ff)转换为四个 6Bit 的字节(3*8 = 4*6 = 24),然后在每个 6Bit 字节前添两位高位 0,组成四个 8Bit 的字节,最后再将每个 8Bit 字节转换成十进制的数字,对应 Base64 编码表(为了保证所输出的编码为可读字符,Base64制定了一个编码表,以便进行统一转换,编码表的大小为 2^6=64,即 Base64 名称的由来)输出编码后的字符。

如果原字节不足 3 的倍数,则用 0 填充,输出字符使用“=”,因此编码后输出的文本末尾可能会出现 1 或 2 个“=”(余数 = 原文字节数 MOD 3 ,如果余数为 1,则要补 2 个“=”,为 2,则补 1 个“=”)。

Base64 编码表 Value Char Value Char Value Char Value Char 0 A 16 Q 32 g 48 w 1 B 17 R 33 h 49 x 2 C 18 S 34 i 50 y 3 D 19 T 35 j 51 z 4 E 20 U 36 k 52 0 5 F 21 V 37 l 53 1 6 G 22 W 38 m 54 2 7 H 23 X 39 n 55 3 8 I 24 Y 40 o 56 4 9 J 25 Z 41 p 57 5 10 K 26 a 42 q 58 6 11 L 27 b 43 r 59 7 12 M 28 c 44 s 60 8 13 N 29 d 45 t 61 9 14 O 30 e 46 u 62 + 15 P 31 f 47 v 63 /

比如:

字符:               f        2         e
ASCII:              102      50        101
3个8Bit字节:        01100110 00110010  01100101
4个6Bit字节:          011001   100011    001001    100101
高位补0:            00011001 00100011  00001001  00100101
十进制:             25       35        9         37
对应码表值:         Z        j         J         l
最终: btoa(f2e) = ZjJl
字符:              b        a        s        e
ASCII:             98       97       115      101
3个8Bit字节:       01100010 01100001 01110011 01100101 00000000 00000000
4个6Bit字节:         011000   100110   000101   110011   011001   010000    000000   000000
高位补0:           00011000 00100110 00000101 00110011 00011001 00010000 00000000 00000000
十进制:            24       38       5        51       25       16
对应码表值:        Y        m        F        z        Z        Q        =        =
最终: btoa(base) = YmFzZQ==

如果将上面的 Base64 编码原理换成接近于编程的思维,过程大致如下(以f2e为例):

注:Base64 编码表我们可以简化为字符串,并通过其进行位置索引:

table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

第一步:

第一个字符 f(102 -> 01100110)通过右移 2 位(first >> 2)获得第一个目标字符(00011001 -> 25),索引编码表中对应的目标字符 Z(table.charAt(first >> 2))。

第二步:

将第一个字符 f(102 -> 01100110)与 3(00000011)进行 AND 运算(first & 3)):
    01100110
AND 00000011
------------
00000010
第一个字符运算后(00000010)再左移 4 位((first & 3) << 4),得:00100000。将第二个字符 2 (50 -> 00110010)右移 4 位(second >> 4),得:00000011。最后将运算后的两个字符进行 OR 运算((first & 3) <> 4):
    00100000
OR  00000011
------------
00100011

获得第二个目标字符(00100011 -> 35),索引编码表中对应的目标字符 j(table.charAt((first & 3) <> 4))。

第三步:

将第二个字符 2 (50 -> 00110010)与 15(00001111)进行 AND 运算(second & 0×0f):
    00110010
AND 00001111
------------
00000010
第二个字符运算后(00000010)再左移 2 位((second & 0×0f) << 2),得:00001000。第三个字符 e(101 -> 01100101)右移 6 位(third >> 6),得:00000001。最后将运算后的两个字符进行 OR 运算((second & 0×0f) <> 6):
    00001000
OR  00000001
------------
00001001

即获得第三个目标字符(00001001 -> 9),索引编码表中对应的目标字符 J(table.charAt((second & 0×0f) <> 6))。

第四步:

取第三个字符 e(101 -> 01100101)的右 6 位(third & 63):
    01100101
AND 00111111
------------
00100101

获得第四个目标字符(00100101 -> 37),索引编码表中对应的目标字符 l(table.charAt(third & 63))。

异常情况:

当第二个字符不存在时(即:余数 = 原文字节数 MOD 3 ,余数为 1),截止至第二步的第 2 小步,然后在最终输出的目标字符后添加两个“=”。当第三个字符不存在时(即:余数 = 原文字节数 MOD 3 ,余数为 2),截止至第三步的第 2 小步,然后在最终输出的目标字符后添加两个“=”。

代码实现如下:

if(!window.btoa) {
window.btoa  = function(text) {
if (/([^u0000-u00ff])/.test(text)) return;
var table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
i = 0,
cur, prev, byteNum,
result=[];    
while(i > 2));
break;
case 2: //second byte
result.push(table.charAt((prev & 3) <> 4)));
break;
case 3: //third byte
result.push(table.charAt((prev & 0x0f) <> 6)));
result.push(table.charAt(cur & 0x3f));
break;
}
prev = cur;
i++;
}
if (byteNum == 1){
result.push(table.charAt((prev & 3) << 4));
result.push("==");
} else if (byteNum == 2){
result.push(table.charAt((prev & 0x0f) << 2));
result.push("=");
}
return result.join("");
}
} 
Tags:Base64  编码  encode 
相关文章
手机版 Js高级编程 Asp之家 Aspxhome.com
闽ICP备06017341号