自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

一文帶你讀懂Base64編碼

開發(fā) 前端
相信很多同學在工作中,經(jīng)常會用到Base64編碼,那大家知道為什么會有Base64編碼嗎?我們?yōu)槭裁匆褂盟?,它又是怎么實現(xiàn)的呢?下面就讓我們來一起深入探究一下Base64編碼吧。

[[385391]]

本文轉(zhuǎn)載自微信公眾號「我是開發(fā)者FTD」,作者FTD。轉(zhuǎn)載本文請聯(lián)系我是開發(fā)者FTD公眾號。  

hi,大家好,我是開發(fā)者FTD。相信很多同學在工作中,經(jīng)常會用到Base64編碼,那大家知道為什么會有Base64編碼嗎?我們?yōu)槭裁匆褂盟兀质窃趺磳崿F(xiàn)的呢?下面就讓我們來一起深入探究一下Base64編碼吧。

Base 家族

在開始之前,我們先給大家介紹一下Base家族。雖然我們在工作中使用最多的是Base64,但是Base家族可不止是只有Base64,除了Base64之外,Base家族還有Base32和Base16。

我們都知道ASCII 編碼,ASCII 編碼是用256(2的8次方)個字符,對二進制數(shù)據(jù)進行編碼的方式,同樣的

  • Base64 編碼是用64(2的6次方)個字符,對二進制數(shù)據(jù)進行編碼的方式
  • Base32 編碼是用32(2的5次方)個字符,對二進制數(shù)據(jù)進行編碼的方式
  • Base16 編碼是用16(2的4次方)個字符,對二進制數(shù)據(jù)進行編碼的方式

那Base家族有這么多編碼形式,為什么偏偏使用Base64呢?

  • Base64 編碼是用64(2的6次方)個特定的ASCII字符來表示256(2的8次方)個ASCII字符,也就是說三個ASCII字符經(jīng)過Base64編碼后變?yōu)樗膫€的ASCII字符顯示(公約數(shù)為24),編碼后數(shù)據(jù)長度比原來增加1/3,不足3n用“=”補足。
  • Base32 編碼就是用32(2的5次方)個特定的ASCII字符來表示256(2的8次方)個ASCII碼,也就是說五個ASCII字符經(jīng)過Base32編碼后會變?yōu)榘藗€ASCII字符顯示(公約數(shù)為40),編碼后數(shù)據(jù)長度比原來增加3/5,不足8n用“=”補足。
  • Base16 編碼就是用16(2的4次方)個特定的ASCII字符表示256(2的8次方)個ASCII字符,也就是說一個ASCII字符經(jīng)過Base16編碼后會變?yōu)閮蓚€ASCII字符顯示,編碼后數(shù)據(jù)長度比原來增加一倍,不足2n用“=”補足。

從上面可以看出Base64編碼后,長度增加是最少的,這也是我們選用Base64的一個重要原因。

Base64 簡介

Base64顧名思義,就是基于64個可打印字符來表示二進制數(shù)據(jù)的一種方法,「注意它并不是一種加密算法」。對于64個打印字符,我們只需要6個二進制位就可以完全表示了。那么我們?nèi)绾卫?個二進制位來表示只需要6個二進制位就可以完全表示的可打印字符呢?由于2的6次方等于64,所以我們可以將每6個位元為一個單元,對應某個可打印字符。三個字節(jié)有24個位元,對應于4個Base64單元,即3個字節(jié)需要用4個可打印字符來表示。

Base64是從二進制數(shù)據(jù)到字符的過程。所以計算機中所有的內(nèi)容,包括文本、圖片、音頻、視頻等等都可以使用Base64編碼來表示。

Base64 編碼原理

Base64編碼就是使用64個字符作為一個基本字符集:

小寫字母a-z、大寫字母A-Z、數(shù)字0-9、符號"+"、"/"(再加上作為墊字的"=",實際上是65個字符)

然后,所有其他符號都根據(jù)一定規(guī)則轉(zhuǎn)換成這個字符集中的字符。

具體來說,Base64編碼的轉(zhuǎn)換方式可以分為以下四步:

  • 第一步,將每三個字節(jié)作為一組,一共是24個二進制位
  • 第二步,將這24個二進制位分為四組,每個組有6個二進制位
  • 第三步,在每組前面加兩個00,擴展成32個二進制位,即四個字節(jié)
  • 第四步,根據(jù)下表,得到擴展后的每個字節(jié)的對應符號,這就是Base64的編碼值

Base64 編碼的字符索引表如下所示:

數(shù)值 字符 數(shù)值 字符 數(shù)值 字符 數(shù)值 字符
0 A 16 Q 32 g 48 w
1 B 17 R 33 h 49 x
2 C 18 S 34 i 50 y
3 D 19 T 35 j 51 z
4 E 20 U 36 k 52 0
5 F 21 V 37 l 53 1
6 G 22 W 38 m 54 2
7 H 23 X 39 n 55 3
8 I 24 Y 40 o 56 4
9 J 25 Z 41 p 57 5
10 K 26 a 42 q 58 6
11 L 27 b 43 r 59 7
12 M 28 c 44 s 60 8
13 N 29 d 45 t 61 9
14 O 30 e 46 u 62 +
15 P 31 f 47 v 63 /

有了這個字符索引表,我們就可以把任意的二進制轉(zhuǎn)換成Base64的編碼了,下面我們通過幾個例子,給大家展示一下轉(zhuǎn)換的過程。

1,假設(shè)現(xiàn)在有字符串 「FTD」 需要轉(zhuǎn)換成base64的編碼格式

 

  • 第一步:“F”、“T”、"D" 字符對應的ASCII碼值分別為70,84,68,對應的二進制值是01000110、01010100、01000100。如圖第二三行所示,由此組成一個24位的二進制字符串。
  • 第二步:將24位二進制按照每6位二進制位一組分成四組。
  • 第三步:在上面每一組前面補兩個0,擴展成32個二進制位,此時變?yōu)樗膫€字節(jié):00010001、00100101、00010001、00000100。分別對應的值(Base64編碼索引)為:17、37、17、4。
  • 第四步:用上面的值在Base64 字符索引表中進行查找,分別對應:R、I、R、E。

因此字符串 “FTD” 經(jīng)過Base64 編碼之后就變?yōu)椋篟IRE 。

2,上面的例子中的字符正好是三個字節(jié),如果字節(jié)數(shù)不足三個時該如何處理呢?下面我們以「F」 和 「FT」 分別舉例說明如下:

 

如上表所示,由于字符F的二進制為01000110,按照每6位進行分組,此時只能分成一組,第二組缺少4位,如果位數(shù)不足時,用0補齊;第三組和第四組完全沒有數(shù)據(jù),則用**=「補上。因此,字符F經(jīng)過Base64編碼后得到的數(shù)值為」Rg==**。

3,下面我們再看一下如果只有兩個字符的情況:

 

如上表所示,這個也屬于位數(shù)不足,需要補位的情況。第一組和第二組按照正常的分組計算,第三組由于不足位數(shù),最后兩位補0,第四組完全沒有數(shù)據(jù),用**=「補上。因此,字符FT經(jīng)過Base64編碼后得到的數(shù)值為」RlQ=**。

關(guān)于中文的Base64編碼

大家都知道中文編碼有很多種,例如「GB2312、GBK、GB18030」,不同的漢字使用不同的編碼格式進行編碼后,它的二進制是不同的,所以在進行Base64編碼后,他們的Base64編碼的值也是不同的。這就要求我們在解碼的時候需要注意原文的字符集格式,一定要保持一致才能正確解碼。

例如:

中文 “【我是開發(fā)者FTD】公眾號” UTF-8 格式的Base64 編碼后的值是:44CQ5oiR5piv5byA5Y+R6ICFRlRE44CR5YWs5LyX5Y+3

中文 “【我是開發(fā)者FTD】公眾號” GB2312 格式的Base64 編碼后的值是:ob7O0srHv6q3otXfRlREob+5q9bausU=

Base64 是加密算法嗎?

Base64 主要不是用來加密的,它主要的用途是把一些二進制數(shù)轉(zhuǎn)成普通字符用于網(wǎng)絡(luò)傳輸,這是因為一些二進制字符在傳輸協(xié)議中屬于控制字符,不能直接在網(wǎng)絡(luò)上傳輸。另外,還有一些系統(tǒng)中只能使用ASCII字符。Base64 編碼就是用來將非ASCII字符的數(shù)據(jù)轉(zhuǎn)換成ASCII字符的一種方法。Base64 并不是安全領(lǐng)域下的加密解密算法,雖然有時候也會經(jīng)??吹剿^的Base64加密解密算法。其實Base64只能算是一個編碼算法,對數(shù)據(jù)內(nèi)容進行編碼來適合網(wǎng)絡(luò)傳輸。雖然Base64編碼過后原文也變成無法直接理解的字符格式,但是這種編碼方式比較初級,很簡單,很容易就可以被還原成原文,所以如果有比較重要的信息需要加密,一定要使用我們之前文章中介紹的那些加密算法進行數(shù)據(jù)的安全保護。

Base64 編碼實現(xiàn)

Java語言中有多個庫實現(xiàn)了Base64編碼,不管哪一個庫,最終的結(jié)果都是一樣的。

JDK 提供的 Base64 編碼實現(xiàn):

  1. public static String encode(String data) { 
  2.     return Base64.getEncoder().encodeToString(data.getBytes()); 
  3.  
  4. public static String decode(String base64Data) { 
  5.     return new String(Base64.getDecoder().decode(base64Data)); 

Bouncy Castle 提供的 Base64 編碼實現(xiàn):

  1. public static String encode(String data) { 
  2.     return new String(Base64.encode(data.getBytes())); 
  3.  
  4. public static String decode(String base64Data) { 
  5.     return new String(Base64.decode(base64Data)); 

Commons Codec 提供的 Base64 編碼實現(xiàn):

  1. public static String encode(String data) { 
  2.     return Base64.encodeBase64String(data.getBytes()); 
  3.  
  4. public static String decode(String base64Data) { 
  5.     return new String(Base64.decodeBase64(base64Data)); 

下面讓我們用Java語言的實現(xiàn)來驗證一下,我們第二章節(jié)的推理是否正確吧,代碼如下:

  1. public static void main(String[] args) { 
  2.     String ftd = "FTD"
  3.     String ft = "FT"
  4.     String f = "F"
  5.  
  6.     System.out.println("FTD base64 編碼:" + encode(ftd)); 
  7.     System.out.println("FT base64 編碼:" + encode(ft)); 
  8.     System.out.println("F base64 編碼:" + encode(f)); 

輸出結(jié)果為:

  1. FTD base64 編碼:RlRE 
  2. FT base64 編碼:RlQ= 
  3. F base64 編碼:Rg== 

可以看到,和我們分析所得的結(jié)果是完全一樣的。

查看完整代碼請訪問:

https://github.com/ForTheDevelopers/JavaSecurity

 

總結(jié)

Base64是我們在工作中經(jīng)常用到,但是很少有人會深入研究一下它的實現(xiàn)原理,如果理解不當,甚至可能還會有人用它當做加解密用到業(yè)務(wù)系統(tǒng)關(guān)鍵位置,可能會引發(fā)比較嚴重的后果,相信大家看完上述的內(nèi)容后,應該對Base64編碼已經(jīng)有了深刻的理解了吧。

 

責任編輯:武曉燕 來源: 我是開發(fā)者FTD
相關(guān)推薦

2021-02-05 05:26:33

字節(jié)ASCII控制

2021-09-13 22:34:56

區(qū)塊鏈新基建數(shù)字化轉(zhuǎn)型

2019-06-13 21:31:19

AI

2021-08-26 05:27:08

Base64 字節(jié)流算法

2014-02-20 10:28:28

JavaScriptBase64

2025-02-11 00:00:10

Base64編碼二進制

2024-02-28 23:07:42

GolangBase64編碼

2020-06-05 14:15:29

可視化數(shù)據(jù)集分析

2024-07-31 10:22:49

Go語言編碼

2018-11-16 10:04:14

云存儲磁帶存儲RAID

2023-12-22 19:59:15

2021-08-04 16:06:45

DataOps智領(lǐng)云

2024-01-29 00:28:01

2022-10-14 17:41:30

字符編碼硬件

2021-09-07 08:59:09

編碼Base64解碼

2019-07-23 08:55:46

Base64編碼底層

2018-09-28 14:06:25

前端緩存后端

2025-04-03 10:56:47

2022-09-22 09:00:46

CSS單位

2022-11-06 21:14:02

數(shù)據(jù)驅(qū)動架構(gòu)數(shù)據(jù)
點贊
收藏

51CTO技術(shù)棧公眾號