我们使用 Java 生成 MD5 时常用的写法如下:
1private static String md5(String data) throws NoSuchAlgorithmException {
2 MessageDigest md = MessageDigest.getInstance("MD5");
3 md.update(data.getBytes());
4 return new BigInteger(1, md.digest()).toString(16);
5}
如果计算 a
的 MD5 会发现结果为 cc175b9c0f1b6a831c399e269772661
,只有 31 位,正确的值应该是 0cc175b9c0f1b6a831c399e269772661
,仔细观察可以发现我们的计算方法把第一位 0
丢失了。
原因出在最后的字符串转换上,MD5 生成字符串是将 byte 数组转成了 BigInteger
,再转成 16 进制表示的字符串,其中转成 BigInteger
时会丢掉前导 0。
只要将字符串生成的地方略作修改即可:
1public static String md5(String data) throws NoSuchAlgorithmException {
2 MessageDigest md = MessageDigest.getInstance("MD5");
3 md.update(data.getBytes());
4 return String.format("%032x", new BigInteger(1, md.digest()));
5}
String.format
的参数如下:
转换符或标志 | 说明 |
---|---|
%x | 整数类型(十六进制) |
0 | 数字前面补 0 |
因此当 string 不满 32 位时,自动在前面补 0。