介绍一下Java MD5加密的两种方式。
1. 第一种是用ava.security.MessageDigest类,简单的使用方法如下:
* MD5加密
* @param input 待加密的字符串
* @return 返回加密后的字符串
*/
public static String generateMD5(String input) throws NoSuchAlgorithmException {
//获取MD5机密实例
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] byteArr = md5.digest(input.getBytes(StandardCharsets.UTF_8));
return byte2hex(byteArr);
}
复制代码
public static String byte2hex(byte[] b) {
StringBuilder hs= new StringBuilder();
String stmp="";
for (byte value : b) {
//为了保证二进制机器数不变,这里需要& 0XFF
stmp = (Integer.toHexString(value & 0XFF));
//如果只有一位,需要在前面补上0凑足两位
if(stmp.length() == 1) {
hs.append("0").append(stmp);
}else {
hs.append(stmp);
}
}
return hs.toString();
}
复制代码
将加密后的数组转换成字符串的过程有一些细节需要注意:
(1)不能直接使用new String(byte[] b),这样得到的字符串是乱码,因为该字符数组并不是由字符串
编码而来,强行解码得到的肯定是乱码。
(2)将单个byte数据转换成16进制字符串需要用到Integer.toHexString(int num)方法,不能直接传入byte数据,如果直接传入byte类型的value,会先将value向上转型为int类型,由于java在将byte类型转成int类型时会保持十进制的值不变,因此当byte为负数时,向上转型就可能改变补码,比如(byte)-10的二进制补码为1111 0110,对应的16进制字符串为f6;其转成int类型后的补码为 1111 1111 1111 1111 1111 1111 1111 0110,对应的字符串fffffff6,因此需要对byte类型的数据作运算:& 0XFF来将高24位置0,从而保证最终得到的字符串是我们想要的。
(3)
if(stmp.length() == 1) {
hs.append("0").append(stmp);
}else {
hs.append(stmp);
}
复制代码
为了保证每个byte数据都转成两位字符串,因此在只有一位时需要在前面补0。比如Integer.toHexString(10) ==>a,需要在前面补上一个0。
2.第二种是用Guava的工具类,这种方法简洁实用,推荐这种方法
/**
* 使用Guava标准包的MD5加密工具
* @param input 待加密的字符串
* @return 返回加密后的字符串
*/
public static String generateMD5(String input) throws UnsupportedEncodingException {
//获取MD5机密实例
return Hashing.md5().hashBytes(input.getBytes("UTF-8")).toString();
}
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END