網站首頁 編程語言 正文
前言
在網絡中傳遞參數時,我們經常會對參數進行Base64編碼,那么Go 語言中如何進行Base64編碼呢?Base64編碼的原理是怎樣的呢?通過這篇文章一起來了解下吧!
Go Base64編碼
標準Base64編碼
// 標準Base64編碼 ?? ?src := "hello world" ?? ?res := base64.StdEncoding.EncodeToString([]byte(src)) ?? ?fmt.Println(res) // aGVsbG8gd29ybGQ= ?? ?// 標準Base64解碼 ?? ?s, err := base64.StdEncoding.DecodeString(res) ?? ?fmt.Println(string(s), err) // hello world <nil>
Base64 URL 編碼
標準Base64編碼后會有 ‘+‘號,在HTTP URL傳輸時,'+‘號會被解析成空格,這樣服務端接收到的數據和傳輸的數據就不一致。因此衍生出了Base64 URL編碼,這種編碼會把’+‘變為’-',便于在URL中傳輸。
因此如果想要將編碼后的數據放在 HTTP URL中傳輸,應該使用該編碼方式。
// Base64 URL 編碼 src := "信息" res := base64.URLEncoding.EncodeToString([]byte(src)) fmt.Println(res) // 5L-h5oGv // Base64 URL 解碼 s, err := base64.URLEncoding.DecodeString(res) fmt.Println(string(s), err) // 信息 <nil>
什么是Base64編碼
Base64是網絡上最常見的用于傳輸8Bit字節碼的編碼方式之一,是一種基于64個可打印字符來表示二進制數據的方法。Base64編碼是從二進制到字符的過程,可用于在HTTP環境下傳遞較長的標識信息。采用Base64編碼具有不可讀性,需要解碼后才能閱讀。—百度百科
通過百度百科的介紹,我們可以獲得如下信息:
- Base64是一種編碼方式,將二進制編碼為字符
- Base64編碼后的字符范圍為64個可打印字符
- 編碼后的結果具有不可讀性,需要解碼:即Base64不是加密方法,而是編碼方式,是從一種語言翻譯為另一種語言,當然也可以翻譯回去
為什么需要Base64編碼
我們都知道計算機的世界,是由0和1組成的,那么0和1的組合如何表示現實語言呢,這就出現了ASCII 碼。ASCII 是由美國設計的,一共128個字符,其中規定了第0~31及127(共33個)是控制字符或通信專用字符,32~126(共95個)是可打印字符。比如10(0000 1001)表示換行,65(0100 0001)表示大寫字母A。
最初的許多協議都是基于 ASCII 設計的,只能傳輸可打印字符。比如發郵件時使用的 SMTP(簡單郵件傳輸協議),最初只能傳輸純文本,對圖片、語音等二進制文件的支持并不是太好。
那么我們想傳輸這些包含不可打印字符的數據怎么辦,一種方式就是設計一種編碼方式,將不可打印字符轉為可打印字符,這樣這些數據就可以傳輸了,收到這些數據后,再解碼回來,得到原始數據。Base64就是為了解決這個問題的。
對于現在的協議來說,都針對二進制文件做了處理,但我們無法保證文件在網絡傳輸過程中不出現問題。當包含不可打印字符的文件在網絡中傳輸時,往往要經過多個路由設備,由于不同的設備(特指老的路由設備)對字節流的處理方式有一些不同,這樣那些不可打印字節就有可能被錯誤處理,不利于數據傳輸的。所以就先把數據先做一個編碼,統統變成可見字節,確保數據可靠傳輸。
Base64編碼原理
Base64之所以叫做Base64,是因為它是基于64個可打印字符設計的,這64個字符是 ASCII 編碼中可打印字符的子集,包含26個字母的大小寫、10個阿拉伯數字、'+‘號 和 ‘/‘號。(其實還有一個 ‘=’ 號用于后綴)
編碼步驟
由于一共有 64 個字符,那么使用 6 個比特位就足夠表示了(2的6次方=64),而 ASCII碼 使用 8 個比特位表示一個字符,6 和 8 的最小公倍數為 24,3個 ASCII碼 字符可以編碼為 4 個 Base64 字符。因此Base64的編碼過程如下:
- 將原始數據每三個字節分為一組,一共24個比特位
- 將24個比特位分為4組,每組6個比特位
- 計算每組的十進制值,根據編碼對照表,得到可打印字符串
以維基百科上舉的例子做個演示:
- 給定單詞 ‘Man’,一共三個字節
- 根據ASCII編碼,得到24個比特位
- 6個一組,分為4組
- 計算每組的十進制值分別為 19、22、5、46,對照Base64編碼表,得到可打印字符串為 ‘TWFu’
需要注意的是,使用Base64編碼后,3個字節會轉為4個字節,編碼后的需要傳輸的數據比編碼前多了 1/3。
位數不足情況
位數不足會有兩種情況:兩個字節或者一個字節的數據。
如果是兩個字節,也就是16個比特,需要補兩個0,得到三個Base64編碼字符,最后添加一個’=‘用于補充
如果是一個字節,也就是8個比特,需要補4個0,得到兩個Base64編碼字符,最后添加兩個’=‘用于補充
Base64解碼原理
解碼就是編碼的逆向操作:
- 去掉結尾的’=‘號
- 根據Base64編碼表,找到每個字符對應的編碼值
- 取每個編碼值的后6位,形成二進制串
- 對上述二進制串,每8個構成一個字節,如果最后一組不夠8個,一定全是0,丟棄掉
- 此時得到的就是原始數據的二進制編碼,再根據編碼方式(例如 ASCII )等進行解碼
例如對于上述 ‘Ma’ 的編碼值 ‘TWE=’ 進行解碼:
- 去掉’=',得到 ‘TWE’
- ‘T’:19,‘W’:22,‘E’:4
- 010011 010110 000100
- 01001101 01100001
- M a
Base64標準編碼變種
我們有時候會將Base64編碼后的字符串,當前 HTTP URL 中的參數進行傳遞,但是標準的 Base64 并不適合直接放在URL里傳輸,因為對于 ‘+‘號,使用url encode時會被encode 為空格,比如編碼后的值是 ‘ab+cd’,但是使用url encode 后變成了 ‘ab cd’,那么對方接收到的也是’ab cd’,此時再解碼肯定失敗了。
為解決此問題,衍生出一種用于URL的改進Base64編碼,它不僅在末尾去掉填充的’=‘號,并將標準Base64中的“+”和“/”分別改成了“-”和“_”。
總結
本篇文章,我們學習了如下內容:
- Go 語言中如何進行 Base64編碼
- Base64編碼和解碼原理
- Base64不是加密算法,而是一種編碼方式
- Base64編碼后的數據量是原數據大小的4/3左右
原文鏈接:https://lifelmy.github.io/post/2022_01_16_go_base64/
相關推薦
- 2022-01-27 workerman執行busy,http請求不返回導致阻塞
- 2022-02-16 瀏覽器斷點如何使用(測試工具)
- 2022-05-31 ASP.NET?Core使用NLog記錄日志_實用技巧
- 2022-10-16 Python?Flask框架使用介紹_python
- 2021-12-03 C/C++表格組件Qt?TableWidget應用詳解_C 語言
- 2023-10-17 前端下載文件時修改文件名
- 2022-05-20 ElasticSearch 7.X系列之:細節問題
- 2022-09-20 Winform使用FTP實現自動更新_C#教程
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支