Hex编码与Base64编码
- 什么是明文
- 什么是编码
- Hex编码
- Hex编码实现细节
- 自定义Hex编码
- Base64编码
- Base64编码实现细节
- 自定义Base64编码
什么是明文
介绍什么是编码之前,首先了解下什么是明文,表示其本身意思的,他就是明文
比如你看到"E6988E",如果是明文他就代表他自己,也就是当他表示"E6988E"时,
但是他如果是Hex编码后的,那他就代表"明"
什么是编码
由于计算机存储的都是二进制数,得通过编码转换成人能认识得东西,中文就是UTF8编码或者Unicode编码后的结果
有些网站不想让你看到他发送至服务端的数据,会通过加密算法对数据进行加密(对字节进行位运算),加密完把字节toString会导致乱码(位运算完的字节大多数无法在UTF8码表或者Unicode编码中找到可见字符),所以有了Hex编码和Base64编码
Hex编码
Hex编码是一种用16个字符(0123456789ABCDEF)表示任意二进制数据的方法,是一种编码,并非加密字符编码,“明"通过Hex编码后是"E6988E”
Hex编码实现细节
//查看com.sun.org.apache.xerces.internal.impl.dv.util下HexBin类可知
static public String encode(byte[] binaryData) {
if (binaryData == null)
return null;
int lengthData = binaryData.length;
//由此可见,Hex编码的字节长度是原字节长度的2倍
int lengthEncode = lengthData * 2;
char[] encodedData = new char[lengthEncode];
int temp;
for (int i = 0; i < lengthData; i++) {
temp = binaryData[i];
//这里是有符号数转无符号数
if (temp < 0)
temp += 256;
//lookUpHexAlphabet就是码表
//取当前字节的高四位
encodedData[i*2] = lookUpHexAlphabet[temp >> 4];
//取当前字节的低四位
encodedData[i*2+1] = lookUpHexAlphabet[temp & 0xf];
}
return new String(encodedData);
}
由此可知,Hex编码就是分别获取前字节的高四位和低四位转换成十进制数,当作索引去码表里面获取对应的字符拼接返回
二进制数00000000-00001111代表的范围是0-15,和码表里面的字符一一对应
PS:8位为一个字节,取出来四位后会在前面补零,然后转10进制
自定义Hex编码
了解清楚Hex编码的实现机制后,就可以开始自定义Hex编码了,能看到这里把HexBin的方法扣过来,编码出来的结果是一样的,改一下码表就能实现自定义Hex编码了
当我们把码表换了后,编码出来的数据与之前完全不一样了,因为相同的索引对应的字符已经不是之前那个了,如果需要解码成功,也需要更换解码的码表,否则会乱码
Base64编码
Base64是一种用64个字符表示任意二进制数据的方法,是一种编码,并非加密字符编码
由 A-Z a-z 0-9 + / 和补充字符 “=” 组成,Base64编码后的字符数是4的倍数(不足会补"=")
Base64编码实现细节
具体和Hex编码类似
Hex编码是4个比特转换成一个新的字符串,Base64是6个比特转换成一个新的字符串,而6个比特(0011 1111)最能表示的十进制数为63,加上0为64,跟进源码可以看出,Base64有俩码表
因为"+“和”/"出现在url中的话,后端接收会出问题
什么时候补"="
比如针对字符"S",字符"S"在UTF8码表中为:83,所以字符串"S"的二进制数为:0101 0011
由于Base64编码以6个比特位一组进行编码,所以可以写为:010100 11
由于不足补零得到二进制数:010100 110000
Base64编码后的字符数是4的倍数所以得到二进制数:010100 110000 000000 000000
然后6个比特为一组,转换成十进制数可得:20和48,由于后面俩组比特位是补位来的,会直接转换成"="字符
在Base64码表中20对应得字符是"U"
在Base64码表中48对应得字符是"w"
PS:标准的Base64码表是A-Z a-z 0-9 + / 按顺序来的
所以字符串"S"的Base64编码结果位:Uw==
自定义Base64编码
和自定义Hex编码同理,修改码表即可,对应解码也需要使用修改后的码表