MD5:
在上一篇《Servlet的学习之Session(5)》中,为了能使获取的所有随机数都能有相同的位数,我们采用MD5获取随机数的消息摘要(或称数据指纹、数据摘要等等)。
MD5可以将所有的数字组合进行一个算法的运算得出一个新的数字组合,并且这个新的数字组合都是128位,也称为MD5码。MD5码是不可逆的,即无法通过MD5码来进行反向运算得到原始的数据。MD5的应用场合非常多,比如保存用户密码(防止数据库中用户密码被管理员看到,所以数据库中的密码不许使用明文密码),或者文件校验(防止下载的文件是被别人修改后的文件而不是官方原文件,比如苹果开发工具的XCodeGhost事件),或者光盘破损校验等等。
在Java中通过MessageDigest对象来调用方法获取某些数字组合的MD5码(顺便说一句,MessageDigest也可以用来获取SHA校验码)。通过MessageDigest对象调用digest方法来将数字组合转变为字符数组:
1 String data = "1"; 2 3 MessageDigest md = MessageDigest.getInstance("md5"); 4 byte[] md5 = md.digest(data.getBytes()); 5 6 System.out.println(Arrays.toString(md5));
获得的字节数组都是128位,即16字节。换句话说经过MD5后的字符数组中有16个元素,因为Java中byte的范围为-128~127,所以每个元素都在这范围内:
注意,经过md5后的字符数组中含有负数元素,因此如果将这个字符数组进行转换成字符串,查询GB2312或者UTF-8都是不合适的会出现乱码例如:
1 String sData = new String(md5,"utf-8"); 2 System.out.println(sData);
那么我们将如何使这个字节数组转换成一个没有乱码的字符串作为一种随机数?我们可以采用“Base64”编码。
Base64编码:
Base64编码是把每3个8位字节(3*8=24)转成4个6位字节(4*6=24),且在每个6位字节前补两个0,重新形成8位一个字节的形式,这样总的长度还是相同的,并且保证最高位不是1(即不是负数)。
如果最后剩下的字符不足3个字符,则用0填充高位,输出字符使用“=”。因此编码后的字符串末尾可能会出现一个或两个“=”。
根据上述原理,最高两位均为0,那么剩下6位全为1二进制对应的十进制为63,所以最大数不会超过63,根据这64个数进行一个码值与字符的对应,就成了base64编码,对应编码表如下图所示:
在Java中我们使用BASE64Encoder对象调用encode方法来将某个字节数组进行编码。
我们将上面的MD5码进行base64编码:
1 BASE64Encoder be = new BASE64Encoder(); 2 String base64 = be.encode(md5); 3 System.out.println(base64);
可以看到这时将乱码都对应成字符了:
注意,BASE64Encoder无法查看其API文档,因为sun公司没有将其正式发布出来,也就没有相应的javadoc文档可以查阅。只能通过下载相应的jar包或者通过网上查阅,如果在开发IDE中发现无法找到sun.misc.BASE64Encode请在网上下载这个JAR包并导入即可。或者请看这篇博客的方法: 《BASE64Encoder及BASE64Decoder的正确用法》