程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> Base64 的那些事兒,Base64事兒

Base64 的那些事兒,Base64事兒

編輯:JAVA綜合教程

Base64 的那些事兒,Base64事兒


一、Base64是什麼?

Base64是一種編碼的格式。是將信息流(字節流)按照一定的規范,重新組合,顯示出完全不相關內容的編碼格式。

ps.定義是我自己總結的,我覺得對於知識的定義,只要簡潔,不錯誤,表述清楚,不要拘泥於一個字一個詞,重要的是真正理解它的原理即可。(其實是因為自己根本不知道標准的定義是什麼...)

二、Base64的由來?

對計算機信息存儲稍有了解的人,都清楚,在計算機內部是以二進制來存儲一切信息的。而直接以二進制為單元進行處理,顯然是不方便處理的,如果數量級過大,我們往往采用增加計數單位的形式。(有興趣的同學可以參考《從1到無窮大》這本書),所以在計算機世(防盜連接:本文首發自http://www.cnblogs.com/jilodream/ )界中就出現了字節這個東西。以每8個bit位組成一個字節。這樣任何信息都可以劃分為占用多少多少個字節來說。如下表所示:

根據大家的認知,大小寫一共52個字母、外加數字加特殊符號等,一個字節是完全可以表述完整的單個字符的(這裡使用的就是ASCII對照表)。

但是對於非英語國家來說就比較頭疼了。發送信息之前翻譯成英語,收到之後再翻譯為本國語言,顯然是成本非常高的。怎麼解決呢?就是使用多個字節來表示一個字符。這樣UTF-8、GBK、UNICODE等編碼就應運而生了(有興趣的同學可以查下它們的區別)。這些編碼基本解決了世界上已知語言在計算中有效存儲流動的問題。

但是問題又來了,有時候我們使用的設備,根本就不支持這些復雜的國際化編碼。

舉個例子,我在家給領導發了封郵件,說最近身體不適,打算請天假去看看外面的世界。

我的表情是這樣的:

 

領導打開郵件之後,發現是一屏幕的亂碼,而且發現我今天沒來。

領導的表情是這樣的:

 

當我心情愉悅的假後來上班時,領導面帶微笑的問我這兩天去哪裡時。

我的表情是這樣的:

 

當領導和我說:電話打不通,郵件是亂碼,人也失蹤的時候。

我的表情是這樣的:

 

 

當我解釋事情是這樣的:巴拉巴拉。

我的表情是這樣的:“這件事情是這樣的,說起來你可能不信 但真的是垃圾桶先動的手”

 

在聽了我的解釋以後。

領導的表情是這樣的:

 

好了言歸正傳,為什麼會出現上游(我)發送的消息,到了下游(領導)就出現無法理解的情況呢?

這是由於歷史原因,早前Email只被允許傳送ASCII字符(不知道現在是否改善),即一個字節的低7位,也就是128種表示。於是當我用各種國際字符發送消息時,勢必就會出現字節的最高位居然是1的問題(防盜連接:本文首發自http://www.cnblogs.com/jilodream/ )。考慮到健壯性和容錯性,有些網絡設備就會把首bit位置換成0。而原本整套的非ASCII碼的字符,就被硬生生的轉成一套ASCII碼。於是當收件者打開郵件進行閱讀時,郵件系統將收到數據硬生生的再轉成非ASCC碼時,一切都晚了。(記得早前,大學老師去歐洲德國留學,給老師寫email只能用拼音)。

其實除去網關,其他路由等硬件設備都會出現這樣那樣的不支持問題。(對於128~255這些不可見字符,不同路由設備在接收後的處理是不一樣的,這也就是為什麼發送信息經常使用轉碼,而不是采用直接傳輸單個字節這一套方法(此處可看http://www.zhihu.com/question/36306744/answer/71626823 郭無心的敘述)。而除去郵件系統,其他很多系統也會因為不支持某些特殊字符,造成發送方和接收方,雙方的信息的不一致。

這裡簡單舉個例子,我們通過互聯網聊天時,數據都是先發送給服務端。服務端發現信息中包含了某個特殊字符,而服務端本身又不支持這個特殊字符。於是就從字庫裡,找到默認字符補填。這樣接收方收到消息時,這個特殊字符就顯示不出來了。取而代之的是一些缺省字符,如‘◇’,‘□’。(ps,印象中QQ游戲是不支持‘.’這個特殊字符的)。

為了解決此類的種種問題,於是Base64就應運而生了。

三、Base64是如何處理字符串編碼的?

這裡先直入正題,闡述關於Base64編碼的情況。

首先明確這樣一個前提,所有信息肯定都是以字節的形式存在的。那麼他的長度對於3這個數字有三種分類:

(1)長度除以3余0:len%3=0;

(2)長度除以3余1:len%3=1;

(3)長度除以3余2:len%3=2;

第(1)情況:

我們把每3個字(防盜連接:本文首發自http://www.cnblogs.com/jilodream/ )節劃分成一份,然後再把它平均拆分成4份。那麼每份就有6個bit位。

3*8bit=24bit=4*6bit

然後每一個單元前邊再加個00,這樣就使得每個單元等等於8位,即一個比特位。

如表,我們可以發現,每個字節真正有效的特征bit位只有6位。2^6=8*8=64。也就是每個字節都可以表現出64種特征。這也正是base64的由來。

第(2)情況:

我們把每3個字節劃分成一份,然後再把它平均拆分成4份。最後剩余1個字節,則拆分成6+2的形式,8bit=6+2bit,如下表:

這裡會涉及到下邊兩種場景

1)對於不足6bit位的單元:這個直接在結尾補0,直到6位。這裡最後剩余2個bit位。

2)對於完全沒有分配的單元,則直接使用“=”放置在單元中。這裡最後補充2個=。

與場景(1)類似,單元格數字前邊補‘0’

第(3)情況

我們把每3個字節劃分成一份,然後再把它平均拆分成4份。最後剩余2個字節,則拆分成6+6+4的形式,16bit=6*2+2bit,如下表:

這裡與場景(2)類似會涉及到下邊兩種場景

1)對於不足6bit位的單元:這個直(防盜連接:本文首發自http://www.cnblogs.com/jilodream/ )接在結尾補0,直到6位。這裡最後剩余4個bit位。

2)對於完全沒有分配的單元,則直接使用“=”放置在單元中。這裡最後補充1個=。

這樣,無論信息的長度是多少,都能以這樣的規則(base64編碼規范),重新劃分成新的字節(符)流。

同時還有一份base64的編碼轉換表:

如下表:

這樣,無論任意的字節流,我們都可以用表中的字符+‘=’來表示了。這就是所謂的Base64編碼過程了。通過Base64編碼,我們可以很好的解決前文中遺留下的問題。

而對於Base64解碼的過程,原理與上述一致,只是一個逆過程,這裡不再贅述。

四、Base64編碼技術的應用

(1) 傳輸數據,盡量做到數據可(防盜連接:本文首發自http://www.cnblogs.com/jilodream/ )以在網絡中正常傳輸,同時不會因為硬件或者軟件不兼容,導致數據失真。

(2) 對數據進行簡單加密,如對於URL或者地址空間的處理(如百度雲地址、p2p鏈接),可以通過簡單的Base64進行簡單的處理,防止肉眼可以直視出這些信息的處理規則。同時也可以有效的進行互聯網信息傳輸。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved