以前用到base64有這麼幾個場景:
但是,圖片轉成base64,體積會變大33%,所以大點的圖片也不建議轉換。
那麼,轉成 base64 為什麼會變大呢?
還有為啥叫 base64, 不叫base16或者base24、base32呢?
針對上面的疑問,我們一步步來解釋,別急,老弟!
假設我們有個單詞要轉成base64: Hello
ASCII值 | 控制字符 | ASCII值 | 控制字符 | ASCII值 | 控制字符 | ASCII值 | 控制字符 |
---|---|---|---|---|---|---|---|
0 | NUT | 32 | (space) | 64 | @ | 96 | 、 |
1 | SOH | 33 | ! | 65 | A | 97 | a |
2 | STX | 34 | " | 66 | B | 98 | b |
3 | ETX | 35 | # | 67 | C | 99 | c |
4 | EOT | 36 | $ | 68 | D | 100 | d |
5 | ENQ | 37 | % | 69 | E | 101 | e |
6 | ACK | 38 | & | 70 | F | 102 | f |
7 | BEL | 39 | , | 71 | G | 103 | g |
8 | BS | 40 | ( | 72 | H | 104 | h |
9 | HT | 41 | ) | 73 | I | 105 | i |
10 | LF | 42 | * | 74 | J | 106 | j |
11 | VT | 43 | + | 75 | K | 107 | k |
12 | FF | 44 | , | 76 | L | 108 | l |
13 | CR | 45 | - | 77 | M | 109 | m |
14 | SO | 46 | . | 78 | N | 110 | n |
15 | SI | 47 | / | 79 | O | 111 | o |
16 | DLE | 48 | 0 | 80 | P | 112 | p |
17 | DCI | 49 | 1 | 81 | Q | 113 | q |
18 | DC2 | 50 | 2 | 82 | R | 114 | r |
19 | DC3 | 51 | 3 | 83 | S | 115 | s |
20 | DC4 | 52 | 4 | 84 | T | 116 | t |
21 | NAK | 53 | 5 | 85 | U | 117 | u |
22 | SYN | 54 | 6 | 86 | V | 118 | v |
23 | TB | 55 | 7 | 87 | W | 119 | w |
24 | CAN | 56 | 8 | 88 | X | 120 | x |
25 | EM | 57 | 9 | 89 | Y | 121 | y |
26 | SUB | 58 | : | 90 | Z | 122 | z |
27 | ESC | 59 | ; | 91 | [ | 123 | { |
28 | FS | 60 | < | 92 | / | 124 | | |
29 | GS | 61 | = | 93 | ] | 125 | } |
30 | RS | 62 | > | 94 | ^ | 126 | ` |
31 | US | 63 | ? | 95 | _ | 127 | DEL |
通過上表可以得知分別為:
算數不好的同學(我)試試這個方法:
13c839f1168e9881a38e6d88f4c5bc81
通過上面可以知道,其實 ASCII 碼隻有128個,也就是 7位就夠瞭,但是存儲確是用的 8 位,每個都是在前面補0,其實已經浪費瞭一些空間。假如說以後字符補充到256個,就可以充分利用空間瞭。
那疑問來瞭,為什麼是6個一組?
首先常用字符有a-z、A-Z、0-9
這些字符總共 26 + 26 + 10 = 62個,另外有找瞭2個湊數的字符 + /
其實我覺得其他字符拿來湊數也是可以的,例如 -、#、[、]等。
2的6次方等於64,也就是6位就足以覆蓋全部的base64字符瞭,所以是6位。
但是存儲還是按8位一組來的,所以要在前面補2個零。
6 和 8 的最小公倍數是24,也就是3個字節,每 6 位一組,也就是4組,每組前面補2個0,湊夠8位。所以這個時候就變成瞭4個字節,也就是增加瞭33.33%
重新分組後新的值為:
85868b6bdfe27f181c0be25b831a1f3c
同樣計算過程為:
索引 | 對應字符 | 索引 | 對應字符 | 索引 | 對應字符 | 索引 | 對應字符 |
---|
最後的結果為:
02922fd4801edb2087c870072846b751
這時候轉換的結果是SGVsbGP
因為規定不足4字節的要在後面補 =
所以結果為SGVsbGP=
本以為這樣就ok瞭,但是我去在線base64 加解密 算瞭下結果為 SGVsbG8=
什麼?最後一位是8? 看瞭下base64 表裡對用的值為60,也就是 parseInt(111100,2)
,仔細想瞭下,每三個字符一組,如果隻有兩個,那最後一個字符就是00000000,分組的時候 就變成瞭111100。所以糾正後的結果為:
表格地址獲取:http://docs.qq.com/doc/DU0tod0JXQ0J3UFRp
前面已經說到ASCII碼有128個,即 2 的 7 次方,一個字節等於8個無符號位,這種情況下,已經浪費瞭 1 個符號位,Base64 是 6位,假如說我們用4位的,也就是2的4次方16,可以命名為Base16,這個時候轉換會有什麼後果呢? 相當於一個字節拆成2個字節,4和8最小公倍數為32,也就是4個字節一組,但是重新組裝後,長度變為原來的2倍,所以體積變為原來的2倍。這時候應該清楚為什麼是Base64瞭吧,就是為瞭減少空間的浪費。那可以發明Base256、或者Base512 這種東西來節省體積嗎?如果是Base256,也就是2的8次方,跟現在的位數一樣,但是用不同的符號代替,則可以保證在不增加體積的情況下完成轉換。如果是Base512,則是9位瞭,一個字節才8位,那就不行瞭。這麼說來Base64 還有優化空間,上限就是Base512,哪天我高興瞭,我也給編個Base512的表,發明Base512編碼,哈哈哈!!!
然而實際情況是我並沒有512個字符可以用
上一篇
Homebrew是一款包管理工具,目前支持macOS和linux系统。主要有四个部分组成: brew、homebrew-core 、homebrew-cask、homebre ...