Android邮件中的Base64和Quoted-Printable编码
田海立@CSDN
2012-07-31
Email在网络上传输时,采用MIME(MultipurposeInternet Mail Extensions)。邮件传输只能传送US-ASCII字符,邮件中包含的其他字符必须通过一定的编码转换之后才能传输。对于Subject或/和附件名称为中文字符的邮件,有些邮件系统因为缺少编码(字符编码和传输编码)信息,导致乱码情况的发生。本文分析Android中Email系统的编码——Base64和Quoted-Printable。
邮件的Subject和附件名,用一种简短的格式指示传输编码和字符编码。字符编码是可以是UTF-8、GB2312等;传输编码常用的有BASE64和Quoted-Printable。本文主要看传输编码,关于字符编码的Unicode编码,可以参考《Unicode编码及其实现:UTF-16、UTF-8, and more》。
一、Base64编码
Base64编码在现在网络传输上应用广泛。Base64可以把要转换的内容,转换成可打印字符(包含字符表’A’~’Z’, ‘a’~’z’, ‘0’~’9’, ‘+’, ‘/’,共64个,以及’=’)。
字符表(64个字符,索引只需6bits,即最大0x3F):
索引
对应字符
索引
对应字符
索引
对应字符
索引
对应字符
0
A
17
R
34
i
51
z
1
B
18
S
35
j
52
0
2
C
19
T
36
k
53
1
3
D
20
U
37
l
54
2
4
E
21
V
38
m
55
3
5
F
22
W
39
n
56
4
6
G
23
X
40
o
57
5
7
H
24
Y
41
p
58
6
8
I
25
Z
42
q
59
7
9
J
26
a
43
r
60
8
10
K
27
b
44
s
61
9
11
L
28
c
45
t
62
+
12
M
29
d
46
u
63
/
13
N
30
e
47
v
?
?
14
O
31
f
48
w
?
?
15
P
32
g
49
x
?
?
16
Q
33
h
50
y
?
?
具体转换规则为:
1. 3字符转换成4个字符;
3个8Bits的字符有24Bits,每6个Bits组成一个BASE64字符表的索引,通过索引找到转换后的字符。
亦即,a7..a0 b7..b0c7..c0 -> A7..A2A1A0B7..B4 B3..B0C7C6C5..C0
A7..A2 第一个字符在字符表中索引;
A1A0B7..B4 第二个字符在字符表中索引;
B3..B0C7C6 第三个字符在字符表中索引;
C5..C0 第四个字符在字符表中索引。
2. 转换后的内容,每76个字符加一个换行符;
3. 最后的不足3个字符的字符要进行特别处理
3.1 若剩余两个字符未处理,则:
这两个剩余的字符与0x00组成一个数据,得到三个字符的索引,最后一个字符用’=’。
亦即,a7..a0 b7..b00..0 -> A7..A2A1A0B7..B4 B3..B000
A7..A2 第一个字符在字符表中索引;
A1A0B7..B4 第二个字符在字符表中索引;
B3..B0 00 第三个字符在字符表中索引;
第四个字符:’=’。
3.2 若剩余一个字符未处理,则:
这个剩余的字符与0x0000组成一个数据,得到两个字符的索引,最后两个字符都用’=’。
亦即,a7..a0 0..00..0 -> A7..A2A1A0 0..0
A7..A2 第一个字符在字符表中索引;
A1A0 0..0 第二个字符在字符表中索引;
第三、第四个字符:‘=’,‘=’。
二、Quoted-Printable编码
Quoted-Printable编码比较简单,扫描要编码的内容,对每个字节进行处理:
如果是空格符(0x20),用‘_’替换; 如果是[33, 127),并且不是特殊限制字符{=_?\"#$%&'(),.:;<>@[\\]^`{|}~},直接用原始字符加入,不做处理; 其他字符,用‘=’加内码信息替换。
三、Email Subject和附件名的表达格式
有了Base64和Quoted-Printable的编码方式,要有一定的格式指示采用的哪种传输编码,同时还要指定编码的字符所采用的字符编码方式。
Email的Subject和附件名的表达格式:<prefix><charset>?<encodeMode>?<encodedContent><suffix>
其中,
<prefix> 固定为“=?”; <charset> 为字符编码格式; <encodeMode> 为传输编码格式:B代表Base64;Q代表Quote-Printable <encodedContent> 为用encodeMode 编码过的字符编码为charset的字符串 <suffix> 固定为“?=”
比如要把“吕晶晶jj9.jpg”作为Subject或者附件名称通过Email传输。编码过程如下:
3.1.UTF-8编码
C3A5C290C295C3A6C299C2B6 C3A6C299C2B6 6A6A392E6A7067吕 晶 晶 j j 9 . j p g