Hex编码与Base64编码

  • 什么是明文
  • 什么是编码
  • Hex编码
  • Hex编码实现细节
  • 自定义Hex编码
  • Base64编码
  • Base64编码实现细节
  • 自定义Base64编码


什么是明文

介绍什么是编码之前,首先了解下什么是明文,表示其本身意思的,他就是明文

比如你看到"E6988E",如果是明文他就代表他自己,也就是当他表示"E6988E"时,
但是他如果是Hex编码后的,那他就代表"明"

什么是编码

由于计算机存储的都是二进制数,得通过编码转换成人能认识得东西,中文就是UTF8编码或者Unicode编码后的结果

有些网站不想让你看到他发送至服务端的数据,会通过加密算法对数据进行加密(对字节进行位运算),加密完把字节toString会导致乱码(位运算完的字节大多数无法在UTF8码表或者Unicode编码中找到可见字符),所以有了Hex编码和Base64编码

Hex编码

Hex编码是一种用16个字符(0123456789ABCDEF)表示任意二进制数据的方法,是一种编码,并非加密字符编码,“明"通过Hex编码后是"E6988E”

esl hex编码格式 hex编码意义_码表

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);
    }

esl hex编码格式 hex编码意义_esl hex编码格式_02

由此可知,Hex编码就是分别获取前字节的高四位和低四位转换成十进制数,当作索引去码表里面获取对应的字符拼接返回
二进制数00000000-00001111代表的范围是0-15,和码表里面的字符一一对应
PS:8位为一个字节,取出来四位后会在前面补零,然后转10进制

自定义Hex编码

了解清楚Hex编码的实现机制后,就可以开始自定义Hex编码了,能看到这里把HexBin的方法扣过来,编码出来的结果是一样的,改一下码表就能实现自定义Hex编码了

esl hex编码格式 hex编码意义_自定义_03


当我们把码表换了后,编码出来的数据与之前完全不一样了,因为相同的索引对应的字符已经不是之前那个了,如果需要解码成功,也需要更换解码的码表,否则会乱码

esl hex编码格式 hex编码意义_自定义_04

Base64编码

Base64是一种用64个字符表示任意二进制数据的方法,是一种编码,并非加密字符编码
由 A-Z a-z 0-9 + / 和补充字符 “=” 组成,Base64编码后的字符数是4的倍数(不足会补"=")

Base64编码实现细节

具体和Hex编码类似

Hex编码是4个比特转换成一个新的字符串,Base64是6个比特转换成一个新的字符串,而6个比特(0011 1111)最能表示的十进制数为63,加上0为64,跟进源码可以看出,Base64有俩码表

esl hex编码格式 hex编码意义_二进制数_05


因为"+“和”/"出现在url中的话,后端接收会出问题

esl hex编码格式 hex编码意义_自定义_06

什么时候补"="
比如针对字符"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==

esl hex编码格式 hex编码意义_码表_07

自定义Base64编码

和自定义Hex编码同理,修改码表即可,对应解码也需要使用修改后的码表