偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

一文帶你讀懂Base64編碼

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

[[385391]]

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

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

Base 家族

在開(kāi)始之前,我們先給大家介紹一下Base家族。雖然我們?cè)诠ぷ髦惺褂米疃嗟氖荁ase64,但是Base家族可不止是只有Base64,除了Base64之外,Base家族還有Base32和Base16。

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

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

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

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

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

Base64 簡(jiǎn)介

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

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

Base64 編碼原理

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

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

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

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

  • 第一步,將每三個(gè)字節(jié)作為一組,一共是24個(gè)二進(jìn)制位
  • 第二步,將這24個(gè)二進(jìn)制位分為四組,每個(gè)組有6個(gè)二進(jìn)制位
  • 第三步,在每組前面加兩個(gè)00,擴(kuò)展成32個(gè)二進(jìn)制位,即四個(gè)字節(jié)
  • 第四步,根據(jù)下表,得到擴(kuò)展后的每個(gè)字節(jié)的對(duì)應(yīng)符號(hào),這就是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 /

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

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

 

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

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

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

 

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

3,下面我們?cè)倏匆幌氯绻挥袃蓚€(gè)字符的情況:

 

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

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

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

例如:

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

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

Base64 是加密算法嗎?

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

Base64 編碼實(shí)現(xiàn)

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

JDK 提供的 Base64 編碼實(shí)現(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 編碼實(shí)現(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 編碼實(shí)現(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語(yǔ)言的實(shí)現(xiàn)來(lái)驗(yà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é)果是完全一樣的。

查看完整代碼請(qǐng)?jiān)L問(wèn):

https://github.com/ForTheDevelopers/JavaSecurity

 

總結(jié)

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

 

責(zé)任編輯:武曉燕 來(lái)源: 我是開(kāi)發(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é)流算法

2020-06-05 14:15:29

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

2014-02-20 10:28:28

JavaScriptBase64

2025-02-11 00:00:10

Base64編碼二進(jìn)制

2024-02-28 23:07:42

GolangBase64編碼

2018-11-16 10:04:14

云存儲(chǔ)磁帶存儲(chǔ)RAID

2024-07-31 10:22:49

Go語(yǔ)言編碼

2021-08-04 16:06:45

DataOps智領(lǐng)云

2023-12-22 19:59:15

2024-01-29 00:28:01

2022-10-14 17:41:30

字符編碼硬件

2019-07-23 08:55:46

Base64編碼底層

2021-09-07 08:59:09

編碼Base64解碼

2023-11-07 08:35:26

2018-09-28 14:06:25

前端緩存后端

2022-09-22 09:00:46

CSS單位

2022-11-06 21:14:02

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

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