在很多加密的场景中,我们需要将字节数组转化为16进制字符串。最近,我在项目中就遇到了此场景,我直接利用BigInteger进行转换,
但是后面发现使用此方式转换有个问题,那就是转换后的数据如果以数字0开头便会被省略掉,例:
本来转换后数据为02c5baefe5fd940b5a12b75dd24e88f1 但是使用此方法转换后数据为2c5baefe5fd940b5a12b75dd24e88f1
特此记录,以备他用,下面提供一种转换方式:
/**
* 对字符串md5加密
*
* @param str
* @return
*/
public static String getMD5(String str) {
StringBuilder sb = null;
try {
// 生成一个MD5加密计算摘要
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(str.getBytes());
//进行哈希计算并返回结果
byte[] btResult = md5.digest();
//使用BigInteger转换的话会省略开头的0
// BigInteger bigInteger = new BigInteger(1, btResult);//将byte数组转换为BigInteger
// str = bigInteger.toString(16);//转化为十六进制的 32 位长度的字符串
String HEX = "0123456789abcdef";
sb = new StringBuilder(btResult.length * 2);
for (byte b : btResult)
{
// 取出这个字节的高4位,然后与0x0f与运算,得到一个0-15之间的数据,通过HEX.charAt(0-15)即为16进制数
sb.append(HEX.charAt((b >> 4) & 0x0f));
// 取出这个字节的低位,与0x0f与运算,得到一个0-15之间的数据,通过HEX.charAt(0-15)即为16进制数
sb.append(HEX.charAt(b & 0x0f));
}
} catch (NoSuchAlgorithmException e) {
if(BuildConfig.DEBUG){
Log.e("Don", "MD5加密失败"+e.getMessage());
}
}
return sb.toString();
}