base64的實現原理

請叫我宋某某發表於2021-07-03

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編碼

具體實現步驟如下:

  1. 字串轉化為2進位制資料
  2. 2進位制資料按照每6位一組分割, 不足6位的補0
  3. 6位二進位制資料轉化為十進位制數
  4. 在對應的base64對映表中找到對應的對映字元,補0的每兩位用一個=號表示

例子

以字串'A'為例

  1. 首先轉為16進位制資料為41對應的二進位制資料為01000001
  2. 每6位二進位制資料分割為一組結果為010000 010000
  3. 6位二進位制轉化為10進位制的結果為16 16
  4. base64對映表對用的字元為Q Q
  5. 因為補了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也不可盲目使用

相關文章