JavaScript 中的 Base64 编码(一):Encode
发布时间:2010-07-23 10:16:00
除了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 eASCII: 102 50 1013个8Bit字节: 01100110 00110010 011001014个6Bit字节: 011001 100011 001001 100101高位补0: 00011001 00100011 00001001 00100101十进制: 25 35 9 37对应码表值: Z j J l最终: btoa(f2e) = ZjJl
字符: b a s eASCII: 98 97 115 1013个8Bit字节: 01100010 01100001 01110011 01100101 00000000 000000004个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)):
01100110AND 00000011------------00000010第一个字符运算后(00000010)再左移 4 位((first & 3) << 4),得:00100000。将第二个字符 2 (50 -> 00110010)右移 4 位(second >> 4),得:00000011。最后将运算后的两个字符进行 OR 运算((first & 3) <> 4):
00100000OR 00000011------------00100011
获得第二个目标字符(00100011 -> 35),索引编码表中对应的目标字符 j(table.charAt((first & 3) <> 4))。
第三步:
将第二个字符 2 (50 -> 00110010)与 15(00001111)进行 AND 运算(second & 0×0f):
00110010AND 00001111------------00000010第二个字符运算后(00000010)再左移 2 位((second & 0×0f) << 2),得:00001000。第三个字符 e(101 -> 01100101)右移 6 位(third >> 6),得:00000001。最后将运算后的两个字符进行 OR 运算((second & 0×0f) <> 6):
00001000OR 00000001------------00001001
即获得第三个目标字符(00001001 -> 9),索引编码表中对应的目标字符 J(table.charAt((second & 0×0f) <> 6))。
第四步:
取第三个字符 e(101 -> 01100101)的右 6 位(third & 63):
01100101AND 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 byteresult.push(table.charAt((prev & 3) <> 4)));break;case 3: //third byteresult.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("");}}
猜你喜欢
- SQL Server数据库快捷键:书签:清除所有书签。 CTRL-SHIFT-F2书签:插入或删除书签(切换)。 CTRL+F2书签:移动到
- 导读:SQL Server数据迁移的知识之前已经为大家介绍了很多,比如SQL Server数据库迁移方法,接下来就为大家详细介绍SQL Se
- 背景 background css 说明 background-image:url(&q
- SQL Server 2000中存在的许多的备份和恢复特性都同样保留在了SQL Server 2005中,但是有一些新的提高同样值得我们关注
- asp连接mysql的问题ASP连接Mysql数据库的问题。下了一个MySql 的ODBC驱动。做了个小测试。顺利通过。先记录下来,中间还有
- '把pattern 又修改了下'code
- 前段时间在论坛上有人问到一个淘宝网上的hover伪类实现的效果如果兼容ie6。其实,问题很简单,就是hover伪类在IE6中得不到很好的支持
- 作为前端开发工程师,平时对于Dom的查找遍历和操作是家常便饭。对于优秀的前端来说,也肯定早已有了自己的一套方法来封装这些重复的操作。但是,现
- 想必大家都知道MSSQL中SA权限是什么,可以说是至高无上。今天我就它的危害再谈点儿,我所讲的是配合NBSI上传功能得到WebShell。在
- JavaScript/Dom中有很多很零碎的东西,让人总是感觉理解的有些“朦胧”,因此,有时候还是应该总结一下,对于Event对象,前两天看
- 1005:创建表失败1006:创建数据库失败1007:数据库已存在,创建数据库失败1008:数据库不存在,删除数据库失败1009:不能删除数
- 要下午传上的.结果事一多,忘记了.好不容易回来 . 这个和 dh20156 的那个,是差不多的。 找不到合适的图片,也
- 什么是SQL 指令植入式攻击?在设计或者维护Web网站时,你也许担心它们会受到某些卑鄙用户的恶意攻击。的确,如今的Web网站开发者们针对其站
- 一旦你已经为MySQL实例管理器设置了一个密码文件并且IM正在运行,你可以连接它。你可以使用mysql客户端工具通过标准MySQL API来
- 数据库计算机 databasecomputer 实现数据库的存储、管理和控制的一种专用计算机系统。它能十分快速而有效地完成各种数据库操作,并
- 假设要生成一千万个随机数,常规的做法如下:var numbers = [];for (var&nbs
- 如何用METADATA替换ADOVBS.INC? 在ASP中,使用组件时,如ADO,得先包含
- <%'asp事务处理。'测试数据库为sql server,服务器为本机,数据库名为test,表名为a,两个字段id(i
- ASCII码键盘ASCII 码键盘ASCII 码键盘ASCII 码键盘27ESC32SPACE33!34"35#36$37%38&
- 原文地址:30 Days of Mootools 1.2 Tutorials - Day 22 - Fx.Elements通过