base64是處理二進位制資料的一種編碼方式,可用於把二進位制資料編碼成64個可列印的字元。
學習base64之前,先了解一下什麼是位元組與編碼
什麼是位元組
網際網路中的資料都是用位元組來表示的,一個位元組有8位二進位制資料組成即00000000 -- 11111111
什麼是編碼
編碼是把字串轉化成二進位制資料的一種方式,計算機發展的過程中,最先定義了ASCII編碼,用於表示英文字元和一些英文字元為128個字元;後來隨著計算機被普及到各國ASCII的編碼已經不能滿足於顯示各國語言的文字,所以說後面發展出了GBK、UNICODE 、UTF8、UTF16等不同型別的編碼,在utf8編碼中一個英文字元佔用1個位元組,一箇中文字元佔用3個位元組
base64編碼表
碼值 | 字元 | 碼值 | 字元 | 碼值 | 字元 | 碼值 | 字元 |
---|---|---|---|---|---|---|---|
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 | / |
base64的實現
base64是,64代表的就是6位二進位制資料,通過把字串轉化為二進位制資料,然後按照每6位二進位制資料來進行分割再把這6位二進位制資料轉化為10進位制數找到對應的對映表就可生成base64編碼
具體實現步驟如下:
- 字串轉化為2進位制資料
- 2進位制資料按照每6位一組分割, 不足6位的補0
- 6位二進位制資料轉化為十進位制數
- 在對應的base64對映表中找到對應的對映字元,補0的每兩位用一個=號表示
例子
以字串'A'
為例
- 首先轉為16進位制資料為
41
對應的二進位制資料為01000001
- 每6位二進位制資料分割為一組結果為
010000 010000
- 6位二進位制轉化為10進位制的結果為
16 16
- base64對映表對用的字元為
Q Q
- 因為補了4個0所以字串
A
對用的base64編碼就為QQ==
程式碼實現
function addZero2Front(str) {
let len = str.length
while (len < 8) {
str = '0' + str
len++
}
return str
}
function getBinary(str) {
const buf = Buffer.from(str)
let binary = ''
for (let i = 0; i < buf.length; i++) {
binary += addZero2Front(
buf[i].toString(2)
)
}
return binary
}
let map = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
function base64(str) {
let binary = getBinary(str)
let num = binary.length % 6
let needAddZeroLen = num !== 0 ? 6 - num : num
let i = needAddZeroLen;
let endStr = ''
let res = ''
while (i > 0) {
binary += '0'
i--
}
i = needAddZeroLen
while ( i > 0) {
endStr += '='
i -= 2
}
i = 0
while (i < binary.length) {
let idx = parseInt(
binary.slice(i, i + 6),
2
)
res += map[idx]
i+=6
}
res += endStr
return res
}
結束語
雖然base64可以便於二進位制資料傳輸且不會造成亂碼;但是值得注意的是,由於base64的性質(把8個位元組轉化為6個位元組儲存),所以不可避免的會把檔案的大小增大1/3,所以base64也不可盲目使用