1. 程式人生 > >從原理上搞定編碼(四)-- Base64編碼

從原理上搞定編碼(四)-- Base64編碼

  開發者對Base64編碼肯定很熟悉,是否對它有很清晰的認識就不一定了。實際上Base64已經簡單到不能再簡單了,如果對它的理解還是模稜兩可實在不應該。大概介紹一下Base64的相關內容,花幾分鐘時間就可以徹底理解它。文章下邊貼了一個Base64的編解碼器,方便閱讀文章的同時來實驗。

  一. Base64編碼由來

  為什麼會有Base64編碼呢?因為有些網路傳送渠道並不支援所有的位元組,例如傳統的郵件只支援可見字元的傳送,像ASCII碼的控制字元就不能通過郵件傳送。這樣用途就受到了很大的限制,比如圖片二進位制流的每個位元組不可能全部是可見字元,所以就傳送不了。最好的方法就是在不改變傳統協議的情況下,做一種擴充套件方案來支援二進位制檔案的傳送。把不可列印的字元也能用可列印字元來表示,問題就解決了。Base64編碼應運而生,Base64就是一種基於64個可列印字元來表示二進位制資料的表示方法。

  二. Base64編碼原理

  看一下Base64的索引表,字元選用了"A-Z、a-z、0-9、+、/" 64個可列印字元。數值代表字元的索引,這個是標準Base64協議規定的,不能更改。64個字元用6個bit位就可以全部表示,一個位元組有8個bit位,剩下兩個bit就浪費掉了,這樣就不得不犧牲一部分空間了。這裡需要弄明白的就是一個Base64字元是8個bit,但是有效部分只有右邊的6個bit,左邊兩個永遠是0。

  那麼怎麼用6個有效bit來表示傳統字元的8個bit呢?8和6的最小公倍數是24,也就是說3個傳統位元組可以由4個Base64字元來表示,保證有效位數是一樣的,這樣就多了1/3的位元組數來彌補Base64只有6個有效bit的不足。你也可以說用兩個Base64字元也能表示一個傳統字元,但是採用最小公倍數的方案其實是最減少浪費的。結合下邊的圖比較容易理解。Man是三個字元,一共24個有效bit,只好用4個Base64字元來湊齊24個有效位。紅框表示的是對應的Base64,6個有效位轉化成相應的索引值再對應Base64字元表,查出"Man"對應的Base64字元是"TWFU"。說到這裡有個原則不知道你發現了沒有,要轉換成Base64的最小單位就是三個位元組

,對一個字串來說每次都是三個位元組三個位元組的轉換,對應的是Base64的四個位元組。這個搞清楚了其實就差不多了。

         

  但是轉換到最後你發現不夠三個位元組了怎麼辦呢?願望終於實現了,我們可以用兩個Base64來表示一個字元或用三個Base64表示兩個字元,像下圖的A對應的第二個Base64的二進位制位只有兩個,把後邊的四個補0就是了。所以A對應的Base64字元就是QQ。上邊已經說過了,原則是Base64字元的最小單位是四個字元一組,那這才兩個字元,後邊補兩個"="吧。其實不用"="也不耽誤解碼,之所以用"=",可能是考慮到多段編碼後的Base64字串拼起來也不會引起混淆。由此可見Base64字串只可能最後出現一個或兩個"=",中間是不可能出現"="的。下圖中字元"BC"的編碼過程也是一樣的。

  三. 總結  

  說起Base64編碼可能有些奇怪,因為大多數的編碼都是由字元轉化成二進位制的過程,而從二進位制轉成字元的過程稱為解碼。而Base64的概念就恰好反了,由二進位制轉到字元稱為編碼,由字元到二進位制稱為解碼。

  Base64編碼主要用在傳輸、儲存、表示二進位制等領域,還可以用來加密,但是這種加密比較簡單,只是一眼看上去不知道什麼內容罷了,當然也可以對Base64的字元序列進行定製來進行加密。

  Base64編碼是從二進位制到字元的過程,像一些中文字元用不同的編碼轉為二進位制時,產生的二進位制是不一樣的,所以最終產生的Base64字元也不一樣。例如"上網"對應utf-8格式的Base64編碼是"5LiK572R",對應GB2312格式的Base64編碼是"yc/N+A=="。

線上Base64編碼器:

相關推薦

原理編碼-- Base64編碼

  開發者對Base64編碼肯定很熟悉,是否對它有很清晰的認識就不一定了。實際上Base64已經簡單到不能再簡單了,如果對它的理解還是模稜兩可實在不應該。大概介紹一下Base64的相關內容,花幾分鐘時間就可以徹底理解它。文章下邊貼了一個Base64的編解碼器,方便閱讀文章的同時來實驗。   一. Base6

原理編碼——BASE64編碼

原文連結:http://www.cnblogs.com/chengxiaohui/articles/3951129.html 開發者對Base64編碼肯定很熟悉,是否對它有很清晰的認識就不一定了。實際 上Base64已經簡單到不能再簡單了,如果對它的理解還是模稜兩可實在不

原理編碼——究竟什麼是編碼?什麼是解碼?什麼是位元組流?

原文:http://www.cnblogs.com/luguo3000/p/3592562.html 編碼問題一直都伴隨著程式猿從不間斷,剛開始學程式設計的時候好多次遇到編碼問題,解 決了檔案讀取的編碼問題,又遇到了網路編碼問題,解決了網路編碼問題又遇到了資料庫編碼問題。總結一下無非就是

python之字符編碼

其余 文本編輯 讀取 文件頭 二進制 ++ 對應關系 都是 信息 一、字符編碼的使用:   1、文本編輯器   unicode----->encode-------->utf-8   utf-8-------->decode---------->un

servlet傳文件

https 創建 res exception threshold poi rac body urn 1.servlet上傳文件   servlet上傳文件就是將客戶端的文件上傳到服務器端。   向服務器發送數據時,客戶端發送的http請求正文采用“multipart/for

輕松RabbitMQ——路由選擇

byte[] view 轉發器 ews 磁盤空間 表示 info 直接 net 轉自 http://blog.csdn.net/xiaoxian8023/article/details/48733249 翻譯地址:http://www.rabbitmq.com/tutori

linux命令快速手記 — 讓手指跟思考的速度

lin 都是 nbsp 管道 tar dem redis安裝 emc tomcat pm2 list:列出pm2方式啟動的所有程序 pm2 monit:顯示每個應用程序的CPU和內存占用情況 scp:遠程復制和本地上傳,適用於本地ssh登錄到遠程服務器   scp root

【Android 進階】仿抖音系列之翻頁下滑切換視訊

大家好,我們又見面了。這是這個系列的第四篇,在這篇文章之前,建議可以先看下之前系列的文章,為了節省篇幅,之前詳細說過的地方,這裡就不再詳細描述了,下面是目錄: 【Android 進階】仿抖音系列之翻頁上下滑切換視訊(一) 【Android 進階】仿抖音系列之列表播放視訊

Client應用場景介紹IdentityServer4

原文: 從Client應用場景介紹IdentityServer4(四) 上節以對話形式,大概說了幾種客戶端授權模式的原理,這節重點介紹Hybrid模式在MVC下的使用。且為實現IdentityServer4從資料庫獲取User進行驗證,並對Claim進行許可權設定打下基礎(第五節介紹)。 本節內容比較多,

零學習遊戲伺服器開發LogServer原始碼探究

這是從零學習開源專案的第四篇,上一篇是《從零學習開源專案系列(三) CSBattleMgr服務原始碼研究》,這篇文章我們一起來學習LogServer,中文意思可能是“日誌伺服器”。那麼這個日誌伺服器到底做了哪些工作呢?我們在Visual Studio中將LogServer設定

Docker在Linux執行NetCore系列使用私有Nuget與多個本地包引用執行ASPNetCore Docker在Linux/Windows執行NetCore文章系列

原文: Docker在Linux上執行NetCore系列(四)使用私有Nuget與多個本地包引用執行ASPNetCore   轉發請註明此文章作者與路徑,請尊重原著,違者必究。         本篇文章演示了使用Docke

輕鬆RabbitMQ——遠端過程呼叫RPC

翻譯:http://www.rabbitmq.com/tutorials/tutorial-six-java.html在第二篇博文中,我們已經瞭解到瞭如何使用工作佇列來向多個消費者分散耗時任務。但是付過我們需要在遠端電腦上執行一個方法然後等待結果,該怎麼辦?這是不同的需求。

C#進階系列——MEF實現設計的“鬆耦合”:建構函式注入

前言:今天十一長假的第一天,本因出去走走,奈何博主最大的樂趣是假期坐在電腦前看各處堵車,順便寫寫部落格,有點收穫也是好的。關於MEF的知識,之前已經分享過三篇,為什麼有今天這篇?是因為昨天分享領域服務的時候,用到MEF的注入有參建構函式的方法,博主好奇心重,打算稍微深挖一下,這篇來對此知識點做個總結。 還是

輕鬆RabbitMQ——工作佇列之訊息分發機制

       上一篇博文中簡單介紹了一下RabbitMQ的基礎知識,並寫了一個經典語言入門程式——HelloWorld。本篇博文中我們將會建立一個工作佇列用來在工作者(consumer)間分發耗時任務。同樣是翻譯的官網例項。 工作佇列        在前一篇博文中,我們完

零開始學習OpenCL開發shader

      這裡介紹關於OpenCL中program函式的寫法,program函式通常是文字形式的,然後使用clCreateProgramWithSource這樣的介面load進來。在Shader程式設計中也經常使用這種形式書寫GPU上執行的程式碼,所以為了表述清楚和理解方

Zedboard執行Linaro系統:檔案系統

轉載請註明,原作者:雅可 ,文章地址:http://blog.csdn.net/yake827/article/details/51980181 下載linaro-utopic-developer-20141212-693.tar.gz 然後我們在/tmp目錄下建立一個l

深入理解計算機系統-之-記憶體--linux中分段機制的實現方式

linux中的分段機制 前面說了那麼多關於分段機制的實現,其實,Linux以非常有限的方式使用分段。因為,Linux基本不使用分段的機制(注:並不是不使用,使用分段方式還是必須的,會簡化程式的編寫和執行方式),或者說,Linux中的分段機制只是為了相容IA

Android2.2平臺支援多camera

三、Camera HAL層支援多Camera 1、CameraHardwareInterface.h檔案 Frameworks/base/include/camera/CameraHardwareInterface.h是Camera HAL層對上的介面檔案。由於它的存在,上層

留言板開始做網站——資料庫的連線和建立

前面基本上把首頁的內容都做好了,現在該是寫send.php的內容了,這個是一個處理檔案,是不用顯示出來的,只是在後臺處理。在填內容前,我們應該先要連線資料庫,新建一個數據庫連線檔案:conn.php。 我們選擇MySQLi的連線方式: <?php $serverna

C# 3.0說以人為本—— Lambda表示式

 重新回到那個用了很多次的語句: IEnumerable<int> numQuery = numbers.Where((number) => number % 2 == 0);  我們知道了Where是擴充套件方法,但是後面的(number) =>