base16, base32, base64 编码讲解

617 阅读6分钟

前言

相信超过绝大多少的程序员都曾在各种的软件开发中使用过编码、解码,编码和解码是对应的,有编码就有解码。

base16,base32,base64 都是编码方式,对应有各自的一套编码算法。
但是有人经常称它们是加密,例如 base64 加密。其实这种说法不算全对。因为默认的 base16,base32,base64 的各种信息都是公开的,公开的包含有:

  • 算法的运算方式
  • 编码表格,这个是主要

在 base16,base32,base64 中,一旦掌握了上面两类信息,那么就相当于破解了。甚至可以手动用笔写出编码后的结果以及根据编码结果写出解码内容。

16,32和64它们编码原理都是一样的,不同的地方在于下面 2 东西:

  • 一个字符所对应表格中的下标的 bit 位是多少个
  • 对应的编码表格是多少

上述两点是什么意思呢?
首先我们知道数据类型 char 一般占2个字节,当然还有二般的情况,比如1个字节,但这里我们以2字节为例,例如: char r = 'a',那么如果这种规则被修改了呢,既然可以使用2个字节表示一个字符,那么为什么不可以用3字节,5字节表示?当我们其它的字节个数表示一个字符的时候,就会产生其它效果。而,上述的第一点就是类似这个意思。当代表下标的 bit 位的个数变了,下标的取值范围也跟着变,比如 2 个 bit 位最大的数是 11 = 3,而 3 个 bit 位最大的数是 111 = 7 。
对于第二点来说,就是一个用来供查表的表格,例如9x9乘法表。这个表格是要被查询的。
编码流程当有了上述两点的条件后,我们将编码的流程总结为下面几点:
例如要被编码的字符串是:ILU

  • 将 ILU 字符串中的每个字符转为对应于 Ascii 编码表的值,I = 73, L = 76, U = 85。
  • 将第一步中的 Ascii 值分别转为对应的二进制格式,要求必须是形成8 个 bit,不足8比特位高位补0。例如:1 的二进制是 1,明显不够8位,最终应该显示为:0000 0001。ILU 的转化结果如下:
    73 = 01001001
    76 = 01001100
    85 = 01010101
  • 根据base X(这里的 X 代表 16,32,64等编号) 编码算法中所指定的y 个 bit 位为一个字符在表格中的下标 的规则,对第2步的进行划分。例如 base 16的规则要求,4位作为一个下标对应一个字符,即每4个位为一部分,故划分如下:
    第1部分:0100 是 (73 = 01001001,的前4个位)
    第2部分:1001 是 (73 = 01001001,的后4个位)
    第3部分:0100
    第4部分:1100
    第5部分:0101
    第6部分:0101
  • 将第三步中划分出的每个部分进行10进制转换,得出对应于10进制数的下标值,如下:
    0100 = 4,1001 = 9,4,12,5,5
  • 最后一步,将第4步中得出的下标数去查表,得出对应的字符,连在一起,就是编码结果
    base16 的默认编码表字符串是:数字0~9和字母A~F,共16个,将每个的下标和值列表格,如下所示:
    base16 的编码表
    下标编码值下标编码值
    0088
    1199
    2210A
    3311B
    4412C
    5513D
    6614E
    7715F
    最终 ILU 的 base16 编码结果是:494C55

自定义表格代码中,我们可以指定自己的编码表,例如下面的一行:
var encoding = base32.NewEncoding("ybndrfg8ejkmcpqxot1uwisza345h769")复制代码ybndrfg8ejkmcpqxot1uwisza345h769 是 32 个字符,对应 base 32 编码,下标 0 对应的字符是 y
当上面的 ILU 例子用 该表格编码时,那么就不再是: 494C55
总结在上面的第3步,对于刚好能够整数划分的 (8 / 4 = 2 整除),是不会有出现在最终结果后面补充等于号"="符号的情况的,而不能除尽的,将会被补充为 "=" 。下面是 16,32和64的需要bit位个数和编码表的总字符
名称下标数字的位个数编码表字符串位数不足是否会补全 =
base 164数字0~9 和 字母 A~F不会,位数刚好是 4 的倍数
base 325大写字母A~Z 和 数字2~7会
base 646大写字母A~Z,小写字母a~z,数字0~9以及"+","/"会名称编码后,数据量变化
base 16由一个8位表示一个字符 变成 4位表示一个字符,数据量变 2 倍
base 32变为 8/5 倍
base 64变为 8/6=4/3 倍补全的限制,拿base32 来说,因为每5位表示一个字符下标值,而原始数据是8位,这就意味着,划分会出现剩下的情况,例如:8 - 5 = 3,明显有3个 bit 位剩下,那么至少要多少个位才能满足步出现剩下的呢?这是一个最小公倍数问题,就是: 5*8 = 40 位。我们可以验证一下,当两个字符的时候,是16位,16/5 = 1,以此类推。
最终,得出在 base32 的编码中,待编码数据至少要 >= 40 位,其最终的编码结果才能不出现 = 号。例如要被编码的字符是3,很明显,它的结果是:D=======,后面的 = 都是补全的。
同理,base64 的是至少 24 位,24 是 6 和 8 的最小公倍数。
上述,就是所有内容,记住此类编码方式的主要点:

  • 一个字符所对应表格中的下标的 bit 位是多少个
  • 对应的编码表格是多少

剩下的,就是照着模式走,划分、对表,得出结果。


链接:https://juejin.cn/post/6844903891973177357
来源:掘金