Base64原理和转换会变大33%左右的原因
Posted JackieDYH
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Base64原理和转换会变大33%左右的原因相关的知识,希望对你有一定的参考价值。
图片转成base64,体积会变大33%,所以大点的图片也不建议转换
base64 生成步骤
例如:有个单词要转成base64: Hello
1. 找到每个字母对应的ASCII值
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 |
通过上表可以得知分别为:
2. 将 ASCII 值转换为二进制
算数不好的同学(我)试试这个方法:
通过上面可以知道,其实 ASCII 码只有128个,也就是 7位就够了,但是存储确是用的 8 位,每个都是在前面补0,其实已经浪费了一些空间。假如说以后字符补充到256个,就可以充分利用空间了。
3. 将 ASCII 的二级制值每6个一组,重新组装(如果不足六位,在前面补0),并计算对应的10进制的值
那疑问来了,为什么是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%
重新分组后新的值为:
同样计算过程为:
4. 接下来就是根据新的值在base64表查找对应的字符了
索引 | 对应字符 | 索引 | 对应字符 | 索引 | 对应字符 | 索引 | 对应字符 |
---|
最后的结果为:
这时候转换的结果是SGVsbGP
因为规定不足4字节的要在后面补 =
所以结果为SGVsbGP=
本以为这样就ok了,但是我去在线base64 加解密算了下结果为
SGVsbG8=
什么?最后一位是8? 看了下base64 表里对用的值为60,也就是
parseInt(111100,2)
,仔细想了下,每三个字符一组,如果只有两个,那最后一个字符就是00000000,分组的时候 就变成了111100。
所以纠正后的结果为:
为什么是Base64,可以是Base16或者Base512吗?
前面已经说到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
以上是关于Base64原理和转换会变大33%左右的原因的主要内容,如果未能解决你的问题,请参考以下文章