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

一篇帶你了解 Base64 原理

開(kāi)發(fā) 前端
Base64 是什么?是將字節(jié)流轉(zhuǎn)換成可打印字符、將可打印字符轉(zhuǎn)換為字節(jié)流的一種算法。Base64 使用 64 個(gè)可打印字符來(lái)表示轉(zhuǎn)換后的數(shù)據(jù)。

[[419497]]

Base64

Base64 是什么?是將字節(jié)流轉(zhuǎn)換成可打印字符、將可打印字符轉(zhuǎn)換為字節(jié)流的一種算法。Base64 使用 64 個(gè)可打印字符來(lái)表示轉(zhuǎn)換后的數(shù)據(jù)。

準(zhǔn)確的來(lái)說(shuō),Base64 不算是一種加、解密的算法,它是一種編碼、解碼的算法。這也是為什么我的用詞是編碼、解碼,而不是加密、解密。

編碼原理

這里的討論的前提是使用 UTF-8 編碼

Base64 算法的原理,是將輸入流中的字節(jié)按每 3 個(gè)分為一組,然后每次取 6 個(gè)比特,將其轉(zhuǎn)換成表格中對(duì)應(yīng)的數(shù)據(jù),一直重復(fù)到?jīng)]有剩余的字符為止,轉(zhuǎn)換表格如下:

編碼過(guò)程

舉個(gè)例子,假設(shè)我們要對(duì)字符串 S.H 進(jìn)行編碼:

  1. 將其轉(zhuǎn)換成十六進(jìn)制為 53、2e、48
  2. 再將十六進(jìn)制轉(zhuǎn)換成二進(jìn)制,分別為 01010011、00101110、01001000。這里不足 8 個(gè)比特的高位補(bǔ) 0 即可。
  3. 將其每6個(gè)比特分為一組,分別為 010100、110010、111001、001000
  4. 將其轉(zhuǎn)換成十進(jìn)制得到,20、50、57、8
  5. 再根據(jù)表格中的轉(zhuǎn)換關(guān)系轉(zhuǎn)換可得,U、y、5、I

換句話說(shuō),字符串 S.H 通過(guò) Base64 算法編碼之后的結(jié)果為 Uy5I 。

編碼圖解

如果覺(jué)得文字較難理解,我把上面的流程用圖的形式畫(huà)了出來(lái),可以結(jié)合著一起看。

為什么要 每三個(gè) 分為一組,因?yàn)?3 8 = 24,24 = 4 6,這樣子可以剛好可以均分完。

那如果我輸入的字節(jié)不足三個(gè)呢?

例如 SH ?按照上述的做法:

首先將其轉(zhuǎn)換成十六進(jìn)制53、48,再將其轉(zhuǎn)換成二進(jìn)制01010011、01001000,再按照每 6 個(gè)比特分為一組,就會(huì)變成 010100、110100、1000,再轉(zhuǎn)換成十進(jìn)制得到 20、52、8,最后得到 U0I.

然而這個(gè)結(jié)果是不正確的,隨便去找一個(gè)工具輸入轉(zhuǎn)換看看都知道,最終結(jié)果為 U0g=. 這也說(shuō)明在輸入的字符不足 3 個(gè)時(shí),就不是按照之前的方式來(lái)處理了。

不足三個(gè)字節(jié)如何處理?

假設(shè)需要編碼的字符串還是 SH。

將其轉(zhuǎn)換成二進(jìn)制為, 01010011、01001000,再按照每 6 個(gè)比特分為一組,就會(huì)變成010100、110100、1000。

但是可以看到最后一組的比特位不足 6 個(gè),在這種情況下,會(huì)進(jìn)行末尾(低位)補(bǔ)0的操作。補(bǔ)完之后就會(huì)變成010100、110100、100000。但是你會(huì)發(fā)現(xiàn),這里總共也只有18個(gè)比特,不滿足 3 個(gè)字節(jié)一組的原則。在這種情況下,前三組會(huì)按照常規(guī)的 Base64 進(jìn)行編碼,而缺失的一組則會(huì)使用 = 來(lái)進(jìn)行填充。

這樣一來(lái),就會(huì)變成20、52、32,再根據(jù)表格轉(zhuǎn)換可得 U0g ,再加上最后填充的 = ,最終結(jié)果就是 U0g=.

以下是圖解。

只有一個(gè)字節(jié)如何處理?

那同理,如果只有一個(gè)字符,最后在二進(jìn)制分組的時(shí)候,不足 6 位的低位補(bǔ) 0,分組不滿 4 的,直接以 = 號(hào)填充。舉個(gè)例子,假設(shè)需要編碼的是字符串 S 。

S 的二進(jìn)制為 01010011 ,按照 6 個(gè)比特分為一組,010100、11。第二組明顯不滿 6 個(gè)比特,進(jìn)行低位補(bǔ)0操作。

低位補(bǔ)0之后結(jié)果變成了010100、110000,這里只有 2 組,不滿四組,所以這里需要填充 2 個(gè) =。將前面的兩組轉(zhuǎn)換成字符,結(jié)果為 Uw,再結(jié)合填充字符,最終的結(jié)果為 Uw==。

關(guān)于編碼,有人可能會(huì)說(shuō),你這都是英文,英文轉(zhuǎn)換成十進(jìn)制再到十六進(jìn)制很方便,對(duì)比 ASCII 碼就行,那要是中文呢?實(shí)際上,這個(gè)跟采取的編碼類(lèi)別有關(guān)系。對(duì)同樣的中文采用不同的編碼,最后得到的結(jié)果可能都不同。所以我們這里只討論采用 UTF-8 的場(chǎng)景。

如果是中文,就采用 UTF-8 將中文進(jìn)行編碼,而如果是英文,其轉(zhuǎn)換結(jié)果和 ASCII 編碼是一樣的。

解碼原理

因?yàn)樽罱K的編碼產(chǎn)物中,如果 6 個(gè)比特的分組不滿 4 組,會(huì)有 = 作為填充物,所以一個(gè) base64 完后的產(chǎn)物總是能夠被 4 整除。

所以,在解密中,我們每次需要處理 4 個(gè)字符,將這 4 個(gè)字符編碼之后轉(zhuǎn)換成十進(jìn)制,再轉(zhuǎn)換成二進(jìn)制,不足 6 位的高位補(bǔ)0,然后將 6 個(gè)比特一組的二進(jìn)制數(shù)按原順序重新分成每 8 個(gè)比特一組,也就是一個(gè)字節(jié)一組。然后將其轉(zhuǎn)換成十六進(jìn)制,再轉(zhuǎn)換成對(duì)應(yīng)的字符。

解碼過(guò)程

假設(shè)我們需要解密的字符為 Uy5I

解密過(guò)程就會(huì)像:

按照每次處理4個(gè)字符的原理,根據(jù)表格將其分別轉(zhuǎn)換成十進(jìn)制20、50、57、8

再將其轉(zhuǎn)換成二進(jìn)制,不足六位的高位補(bǔ)0,再將其分成每 8 個(gè)比特一組

將分組好的比特轉(zhuǎn)換成十六進(jìn)制,得到53、2e、48

最后將十六進(jìn)制轉(zhuǎn)換成字母得到S、.、H,也就是 S.H

解碼圖解

換成圖片來(lái)說(shuō)就是如下這樣

這里我們處理的是一個(gè)比較理想的情況,因?yàn)樗械谋忍匚粍偤帽惶畛渫辏侨绻麕в?= padding 的 base64 是如何進(jìn)行解密的呢?

這里拿 SH 編碼之后的 base64 字符串 U0g= 來(lái)做例子

  1. 首先根據(jù)表格,將其轉(zhuǎn)換成十進(jìn)制20、50、32
  2. 再將其轉(zhuǎn)換成二進(jìn)制,不足 6 個(gè)比特的高位補(bǔ)0,010100、110100、100000
  3. 再將其分成每 8 個(gè)比特位一組,01010011、01001000、
  4. 然后再轉(zhuǎn)換成十六進(jìn)制得53、48
  5. 轉(zhuǎn)換成字符串可得 SH

 

責(zé)任編輯:姜華 來(lái)源: SH的全棧筆記
相關(guān)推薦

2019-07-23 08:55:46

Base64編碼底層

2021-08-11 07:02:21

npm包管理器工具

2022-02-18 08:54:21

docker操作系統(tǒng)Linux

2021-05-20 06:57:16

RabbitMQ開(kāi)源消息

2021-03-05 09:10:19

base64編碼

2021-08-02 06:34:55

Redis刪除策略開(kāi)源

2021-11-08 08:42:44

CentOS Supervisor運(yùn)維

2021-11-24 08:51:32

Node.js監(jiān)聽(tīng)函數(shù)

2021-12-15 11:52:34

GPLLinuxGNU

2023-05-12 08:19:12

Netty程序框架

2021-06-30 00:20:12

Hangfire.NET平臺(tái)

2021-07-28 10:02:54

建造者模式代碼

2021-07-14 08:24:23

TCPIP 通信協(xié)議

2025-02-11 00:00:10

Base64編碼二進(jìn)制

2022-04-08 08:32:40

mobx狀態(tài)管理庫(kù)redux

2023-07-30 15:18:54

JavaScript屬性

2022-05-05 07:40:07

maskCSS

2023-05-08 08:21:15

JavaNIO編程

2021-01-26 23:46:32

JavaScript數(shù)據(jù)結(jié)構(gòu)前端

2021-03-09 14:04:01

JavaScriptCookie數(shù)據(jù)
點(diǎn)贊
收藏

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