常见的Base编码分为三种:Base64、Base32、Base16
一、Base64编码
1、主要内容
Base64编码是使用64个可打印的ASCII字符(A-Z、a-z、0-9、+、/)将任意字节序列数据编码成ASCII字符串。另有"="符号用作后缀用途。
数值 | 字符 | 数值 | 字符 | 数值 | 字符 | 数值 | 字符 | |||
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是基于64个可打印字符来表示二进制数据的编解码方式。正因为是可编解码,所以它主要的作用不在于保证安全性,而在于让内容能在各个网关间无错的传输。
2、 实现原理:
将三字节变成四字节 ( 3 * 8=4 * 6)
由于64等于2的6次方,所以一个Base64字符实际上代表着6个二进制位(bit)。
然而,二进制数据1个字节(byte)对应的是8比特(bit),因此,3字节(3 x 8 = 24比特)的字符串/二进制数据正好可以转换成4个Base64字符(4 x 6 = 24比特)。
为什么是3个字节一组呢? 因为6和8的最小公倍数是24,24比特正好是3个字节。
例:
原文 | w | a | n | ||||||||||||||||||||||||||||||||
ASCII码 | 119 | 97 | 110 | ||||||||||||||||||||||||||||||||
二进制位 | 0 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | 1 | 0 | |||||||||||
6 bit 切分 | 0 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | 1 | 0 | |||||||||||
高位补全 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 0 | |||
Base64编码 | d | 2 | F | u |
则 'wan' base64 编码后为: d2Fu
但要是遇到转换字节数不是24的倍数怎么办?
在八位转六位时,可能会有余两位或者余四位的情况,此时继续补0凑够八位时,在解码时会出现多余的位。所以为了解决这个问题,base64引入了 ' = ',一个' = '表示六个二进制位0。当补两个0时,补一个=凑够8位;补4个0时时,补两个=,凑够16位变成8的倍数。而在解码的时候,在末尾补的两个0与一个“=”相消表示一个空字符,不影响正常解码。
之所以凑成8的倍数,是因为base64主要用于加密后的数据传送,而传送中认为最小的传送单位是字节,所以总位数都是8的倍数。
则:末尾每需要补两个0时,密文需要补一个=相消。且最多会出现两个=号。
例:
原文 | S | B | ||||||||||||||||||||||||
ASCII码 | 83 | 66 | ||||||||||||||||||||||||
二进制位 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | ||||||||||
切分-补全 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | ||||||||
高位补全 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | ||
Base32编码 | U | 0 | I |
则 'SB' base32 编码后为:U0I=
3、Base64隐写原理
在对base64进行解码时,存在占位符=的情况下,会将末尾的=跟末尾加上0相消产生空字符,所以不影响原文的读取。那么通过改变末尾补全的几位比特,就会改变base64编码后文本的显示,但是并不会改变解码后原文的内容。
那么我们如何判断一个base64编码后的文本是否使用了隐写呢?
1、我们可以通过对编码进行解码,查看其末尾是否用0进行的填充。
2、我们可以使用base64编码工具进行解码,然后再编码,对比编码后的文本是否一致进行判断。如果不一致则存在base64隐写。
4、特点
-
将二进制数据转为字符串(ASCII码),方便数据传输。
-
浏览器能直接展示Base64编码图片,减少请求。
-
编码后数据会大至少三分之一,需要额外的方法处理编解码。
二、Base32编码
与base64编码原理相同,不过是Base32使用了ASCII编码中可打印的32个字符(大写字母AZ和数字27)对任意字节数据进行编码.Base32将串起来的二进制数据按照5个二进制位分为一组,由于传输数据的单位是字节(即8个二进制位).所以分割之前的二进制位数是40的倍数(40是5和8的最小公倍数).
数值 | 字符 | 数值 | 字符 | 数值 | 字符 | 数值 | 字符 | |||
0 | A | 8 | I | 16 | Q | 24 | Y | |||
1 | B | 9 | J | 17 | R | 25 | Z | |||
2 | C | 10 | K | 18 | S | 26 | 2 | |||
3 | D | 11 | L | 19 | T | 27 | 3 | |||
4 | E | 12 | M | 20 | U | 28 | 4 | |||
5 | F | 13 | N | 21 | V | 29 | 5 | |||
6 | G | 14 | O | 22 | W | 30 | 6 | |||
7 | H | 15 | P | 23 | X | 31 | 7 |
如何使用=填充呢?
1、首先使用0补全切分后的末尾,使得补全后的二进制位数可以整除5。即可以得到得到完整的base32编码值。
2、补全后由于多了数个0,则在进行解码时需要消除增加在末尾的0,那么依旧采用=相消。每一个=代表五位二进制,与增加在末尾的0凑足能够整除8的二进制位数,目的是在解码时五位 base32编码 转换为八位 ASCII码 时不会有余位。
3、对于在末尾增加不同数的0,分为以下几种情况:
• input的长度(bit)是5(也可以理解为40)的整数倍,不需要填充• 多出来1bit,需要使用4个0在末尾补全,4个0需要四个=相消。即 8 % (4+4×5)==0;
• 多出来2bit,需要使用3个0在末尾补全,3个0需要一个=相消。即 8 % (3+1×5)==0;
• 多出来3bit,需要使用2个0在末尾补全,2个0需要六个=相消。即 8 % (2+6×5)==0;
• 多出来4bit,需要使用1个0在末尾补全,1个0需要三个=相消。即 8 % (1+3×5)==0;
例:
原文 | S | B | |||||||||||||||||||||||||||||||||
ASCII码 | 83 | 66 | |||||||||||||||||||||||||||||||||
二进制位 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | |||||||||||||||||||
切分-补全 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | |||||||||||||||
Base32编码 | K | N | B | A |
则 'SB' base16 编码后为:KNBA====
三、Base16编码
Base16编码就是将ASCII字符集中可打印的字符(数字0~9和字母A~F)对应的二进制字节数据进行编码,编码的方式:
1.将数据(根据ASCII编码,UTF-8编码等)转成对应的二进制数,不足8比特位高位补0.然后将所有的二进制全部串起来,4个二进制位为一组,转化成对应十进制数.
2.根据十进制数值找到Base16编码表里面对应的字符.Base16是4个比特位表示一个字符,所以原始是1个字节(8个比特位)刚好可以分成两组,也就是说原先如果使用ASCII编码后的一个字符,现在转化成两个字符.数据量是原先的2倍.
数值 | 字符 | 数值 | 字符 | |
0 | 0 | 8 | 8 | |
1 | 1 | 9 | 9 | |
2 | 2 | 10 | A | |
3 | 3 | 11 | B | |
4 | 4 | 12 | C | |
5 | 5 | 13 | D | |
6 | 6 | 14 | E | |
7 | 7 | 15 | F |
例:
原文 | S | B | |||||||||||||||||||||||||||||||||
ASCII码 | 83 | 66 | |||||||||||||||||||||||||||||||||
二进制位 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | |||||||||||||||||||
切分-补全 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | |||||||||||||||||||
Base16编码 | 5 | 3 | 4 | 2 |