Files
2012-10-30 20:31:20 +08:00

125 lines
7.5 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-14T16:38:17+08:00
====== Base64 ======
Created Friday 14 October 2011
http://zh.wikipedia.org/zh-cn/Base64
Base64是一种使用__64基__的__位置计数法__。它使用2的最大次方来代表__仅可打印__的ASCII 字符。这使它可用来作为电子邮件的__传输编码__。在Base64中的变量使用字符A-Z、a-z和0-9 ,这样共有62个字符,用来作为开始的64个数字,最后两个用来作为数字的符号在不同的系统中而不同。一些如uuencode的其他编码方法,和之后binhex的版本__使用不同的64字符集__来代表6个二进制数字,但是它们不叫Base64。
目录
1 MIME
1.1 例子
2 UTF-7
3 IRCu
4 在URL中的应用
5 其他应用
6 外部链接
7 参见
===== MIME =====
在MIME格式的电子邮件中,base64可以用来将binary的__字节序列__数据编码成ASCII字符序列构成的__文本__。使用时,在传输编码方式中__指定base64__。使用的字符包括大小写字母各26个,加上10个数字,和加号“+”,斜杠“/”,一共64个字符,等号“=”用来作为__填充后缀__用途。
完整的base64定义可见 RFC 1421和 RFC 2045。编码后的数据比原始数据**略长**,为原来的4/3。在电子邮件中,根据RFC 822规定,__每76个字符(转换后的字节字符数),还需要加上一个回车换行。可以估算编码后数据长度大约为原长的135.1%__。
转换的时候,将__三个__byte的数据,先后放入一个24bit的缓冲区中,先来的byte占高位。数据不足3byte的话,于缓冲区中剩下的bit用0补足。然后,每次取出6(因为26 = 64)个bit,按照其值选择ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/中的字符作为编码后的输出。不断进行,直到全部输入数据转换完成。
如果最后剩下两个输入数据,在编码结果后加1个“=”;如果最后剩下一个输入数据,编码结果后加2个“=”;如果没有剩下任何数据,就什么都不要加,这样才可以保证资料还原的正确性。
举例来说,一段引用自托马斯·霍布斯的利维坦的文句:
Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.
经过base64编码之后变成:
TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz
IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg
dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu
dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo
ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=
编码“Man”
文本 M a n
ASCII编码 77 97 110
二进制位 0 1 0 0 1 1 0 1 0 1 1 0 0 0 0 1 0 1 1 0 1 1 1 0
索引 19 22 5 46
Base64编码 T W F u
在此例中,Base64算法将三个字符编码为4个字符
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 /
===== UTF-7 =====
UTF-7 是一个修改的Base64(Modified Base64)。主要是将UTF-16的数据,用Base64的方法编码为可打印的 ASCII 字符序列。目的是传输 Unicode 数据。主要的区别在于__不用等号"="补余__,因为该字符通常需要大量的转译。
标准可见RFC 2152,《A Mail-Safe Transformation Format of Unicode》。
===== IRCu =====
在IRCu等软件所使用的P10 IRC服务器间协议中,对客户与服务器的消息类型号(client/server numerics)和二进制IP地址采用了base64编码。消息类型号的长度固定为3字节,故可直接编码为4个字节而不需要加填充。对IP地址进行编码时,则需要在地址前添加一些0比特,使之可以编码为整数个字节。这里所用的符号集与前述MIME的也有所不同,__将+/改成了[]__。
===== 在URL中的应用 =====
Base64编码可用于在HTTP环境下传递较长的__标识信息__。例如,在Java持久化系统Hibernate中,就采用了Base64来将一个较长的唯一标识符(一般为128-bit的UUID)编码为一个字符串,用作HTTP表单和HTTP GET URL中的参数。在其他应用程序中,也常常需要把**二进制数据编码**为适合放在URL(包括隐藏表单域)中的形式。此时,采用Base64编码不仅比较简短,同时也具有不可读性,即所编码的数据不会被人用肉眼所直接看到。
然而,标准的Base64并不适合直接放在URL里传输,因为__URL编码器会把标准Base64中的“/”和“+”字符变为形如“%XX”的形式__,而这些“%”号在存入数据库时还需要再进行转换,因为ANSI SQL中已将“%”号用作通配符。例如:
>>> "测试"
'\xe6\xb5\x8b\xe8\xaf\x95' #“测试"的utf-8编码
>>> urllib.quote("测试.djfkdj_dkfj") __ #URL编码时字母、数字、下划线、逗号、句号、连字符都不变,其它的所有字符转换为“%XX”的转意序列。__
__#这里中文的转意序列为其UTF-8编码,注意用%分割不同的字节。__
'%E6%B5%8B%E8%AF%95.djfkdj_dkfj'
>>> urllib.quote("测试.djfkdj_dkfj_23,jdk343k-3w43_dkfj$")
'%E6%B5%8B%E8%AF%95.djfkdj_dkfj_23%2Cjdk343k-3w43_dkfj**%24**'
>>> urllib.quote("测试.djfkdj_dkfj_23,jdk343k-3w43_dkfj$~`'")
'%E6%B5%8B%E8%AF%95.djfkdj_dkfj_23%2Cjdk343k-3w43_dkfj**%24%7E%60%27**'
>>>
为解决此问题,可采用一种用于URL的改进Base64编码,它不在末尾填充'='号,并__将标准Base64中的“+”和“/”分别改成了“*”和“-”__,这样就免去了在URL编解码和数据库存储时所要作的转换,避免了编码信息长度在此过程中的增加,并统一了数据库、表单等处对象标识符的格式。
另有一种用于正则表达式的改进Base64变种,它将“+”和“/”改成了“!”和“-”,因为“+”,“*”以及前面在IRCu中用到的“[”和“]”在正则表达式中都可能具有特殊含义。
此外还有一些变种,它们将“+/”改为“_-”或“._”(用作编程语言中的标识符名称)或“.-”(用于XML中的Nmtoken)甚至“_:”(用于XML中的Name)。
===== 其他应用 =====
* Mozilla Thunderbird和Evolution用Base64来保密电子邮件密码
* Base64 也会经常用作一个__简单的“加密”__来保护某些数据,而真正的加密通常都比较繁琐。
* 垃圾讯息传播者用Base64来避过反垃圾邮件工具,因为那些工具通常都不会翻译Base64的讯息。
* 在LDIF档案,Base64用作编码字串。
===== 外部链接 =====
RFC 1421 (Privacy Enhancement for Electronic Internet Mail)
RFC 2045 (MIME)
RFC 3548 (The Base16, Base32, and Base64 Data Encodings)
Base64在线转换工具
Home of the Base64 specification, with an online decoder and C99 implementation
不同编程语言/应用程式的源代码/工具:
C
Java
MIME::Base64 Perl module
Firefox extension
emacs函数