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也不可盲目使用