| 5 MIME郵件的編碼方式由于每個(gè)ASCII碼字符只占用一個(gè)字節(jié)(8個(gè)bit位),且最高bit位總為0,即ASCII碼字符中的有真正意義的信息只是后面的7個(gè)低bit位,而傳統(tǒng)的SMTP協(xié)議又是基于ASCII碼字符設(shè)計(jì)的,因此,一些基于傳統(tǒng)SMTP協(xié)議設(shè)計(jì)的SMTP服務(wù)器在處理郵件內(nèi)容時(shí)只取出每個(gè)字節(jié)中的7個(gè)低bit位進(jìn)行處理,而將最高bit位忽略不計(jì)。顯然,這樣的SMTP服務(wù)器在處理包含有非ASCII碼字符的郵件內(nèi)容時(shí),會(huì)出現(xiàn)嚴(yán)重的問題,這就限制了郵件中只能出現(xiàn)英文的ASCII碼字符,而不能出現(xiàn)中文字符或二進(jìn)制數(shù)據(jù)。 為了能夠在郵件內(nèi)容中包含中文、圖像或聲音等非ASCII字符的數(shù)據(jù),人們想到了采用某種編碼方式將非ASCII字符的數(shù)據(jù)轉(zhuǎn)換成可打印的ASCII字符后再發(fā)送,郵件閱讀程序則按照相應(yīng)的解碼方式從郵件中還原出原始數(shù)據(jù)即可,比較常用的兩種郵件編碼方式為BASE64和Quoted-printable。后來的擴(kuò)展SMTP協(xié)議允許直接在郵件中傳遞二進(jìn)制數(shù)據(jù),而不用對(duì)它們進(jìn)行郵件編碼,人們將這種沒有進(jìn)行郵件編碼的二進(jìn)制數(shù)據(jù)的郵件內(nèi)容稱為8bit編碼,為了與此相區(qū)別,人們將沒有進(jìn)行郵件編碼的純ASCII碼字符的郵件稱為7bit編碼。MIME消息體的郵件編碼方式通過MIME消息頭中的Content- Transfer- Encoding頭字段指定,每種郵件編碼方式的介紹如下: — 7Bit 指消息體內(nèi)容全部是沒有經(jīng)過編碼的ASCII字符。 
 — 8Bit 指消息體內(nèi)容是沒有經(jīng)過編碼的原始數(shù)據(jù),且其中包含有非ASCII字符的數(shù)據(jù)?,F(xiàn)在的郵件服務(wù)器基本上都支持8Bit編碼,使用支持8Bit編碼的郵件服務(wù)器可以簡(jiǎn)化郵件的處理過程。 
 — BASE64 Base64是將二進(jìn)制數(shù)據(jù)轉(zhuǎn)換成可打印的ASCII字符的一種最常見的編碼方式,它的基本原理是將一組連續(xù)的字節(jié)數(shù)據(jù)按6個(gè)bit位進(jìn)行分組,然后對(duì)每組數(shù)據(jù)用一個(gè)ASCII字符來表示。6個(gè)bit位最多能表示26=64個(gè)數(shù)值,因此可以使用64個(gè)ASCII字符來對(duì)應(yīng)這64個(gè)數(shù)值,這64個(gè)ASCII字符為: 
 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" 
 其中每個(gè)字符表示的數(shù)值就是該字符在上面的排列中的索引號(hào),索引號(hào)從0開始編號(hào)。假設(shè)在內(nèi)存中有如下三個(gè)連續(xù)的字節(jié)數(shù)據(jù):[0110,0001] [0110,0010] [0110,0011] 
 將它們按6個(gè)bit位進(jìn)行分組后的形式如下: [0110,00] [01,0110,] [0010,01] [10,0011] 
 分組后得到了四組數(shù)據(jù),每組數(shù)據(jù)對(duì)應(yīng)的十進(jìn)制數(shù)值分別為24、22、9、35,它們分別對(duì)應(yīng)Y、W、J、j這四個(gè)字符,所以,對(duì)[0110,0001] [0110,0010] [0110,0011]這三個(gè)字節(jié)的數(shù)據(jù)進(jìn)行BASE64編碼后的結(jié)果是“YWJj”。 
 BASE64編碼要求把3個(gè)8位字節(jié)(即24個(gè)bit)的數(shù)據(jù)轉(zhuǎn)化為4個(gè)6位字節(jié)(也是24個(gè)bit)的數(shù)據(jù),如果原來的8位字節(jié)數(shù)據(jù)的字節(jié)個(gè)數(shù)不能被3整除,其余數(shù)只能是1或2,那么如何對(duì)余下的1個(gè)或2個(gè)8位字節(jié)數(shù)據(jù)進(jìn)行處理呢?對(duì)于這種情況,仍然按6個(gè)bit位對(duì)剩余的字節(jié)進(jìn)行分組,在最后不夠6個(gè)bit位的內(nèi)容后面添加幾個(gè)為0的bit位來湊成6個(gè)bit位,例如,如果最后剩下的一個(gè)8位字節(jié)的內(nèi)容如下:[0110,0001] 
 對(duì)它進(jìn)行分組后的結(jié)果如下: [0110,00] [01,0000] 
 其中用黑斜體標(biāo)識(shí)的0為填充的bit位,所以,最后剩下的這個(gè)字節(jié)的BASE64編碼結(jié)果為“YQ”。BASE64編碼還有規(guī)定,如果編碼后的整個(gè)結(jié)果文本的字符個(gè)數(shù)不是4的整數(shù)倍,那么需要在最后填充“=”字符來湊成4的倍數(shù),所以,在最后這個(gè)字節(jié)編碼的結(jié)果后面還要添加兩個(gè)“=”字符,即“YQ==”。顯然,如果最后剩下兩個(gè)8位字節(jié)的內(nèi)容,它可以被編碼成三個(gè)字符,最后還需要添加一個(gè)“=”字符。對(duì)一大段數(shù)據(jù)進(jìn)行BASE64編碼時(shí),可以在編碼結(jié)果中的適當(dāng)位置加入回車換行,MIME規(guī)范建議BASE64編碼結(jié)果中的每行最多76個(gè)字符。 
 — Quoted-printable Quoted-printable也是一種將二進(jìn)制數(shù)據(jù)轉(zhuǎn)換成可打印的ASCII字符的編碼方式,它對(duì)ASCII字符不進(jìn)行轉(zhuǎn)換,只對(duì)非ASCII字符的數(shù)據(jù)進(jìn)行編碼轉(zhuǎn)化。每個(gè)非ASCII字符的字節(jié)數(shù)據(jù),都被轉(zhuǎn)換成一個(gè)"="號(hào)后跟這個(gè)字節(jié)的十六進(jìn)制數(shù)據(jù),例如,“ab中國(guó)”的Quoted-printable編碼結(jié)果為“ab=d6=d0=b9= fa”。顯然,由于"="號(hào)在Quoted-printable編碼中具有的特殊意義,所以,原始數(shù)據(jù)中的"="號(hào)字符也需要進(jìn)行編碼轉(zhuǎn)換,用“=3d”表示。 
 對(duì)一大段數(shù)據(jù)進(jìn)行Quoted-printable編碼時(shí),可以在編碼結(jié)果中的適當(dāng)位置加入回車換行,在回車換行前需要額外再加入一個(gè)“=”字符,以表示后面的換行是因編碼而造成的軟回車,而非原始數(shù)據(jù)中原有的回車換行。例如,對(duì)于下面一段Quoted-printable編碼后的數(shù)據(jù): =D5=E2=CA=C7=CD=A8=D0=C5=B5=C4=B3=CC=D0= =F2, =C7=EB=D6=B8=BD=CC! 
 在第一行末尾的“=”字符和換行,都是由于編碼后生成的。 | 
|  |