关于MD5加密中byte数组转换成16进制字符串的研究
简介:四种md5加密,主要区别在于将md5加密后的byte数组转换为16进制字符串的⽅式。
1.第⼀种,使⽤bigInteger进⾏转换
public static String md5Encrypt(String src){
try {
//获取md5算法
MessageDigest md5Digest = Instance("md5");
//将要加密的字符串转为byte数组进⾏加密
byte[] digest = md5Digest.Bytes("utf-8"));
//将加密后的byte数组转换成⼗六进制字符串
/**
* public BigInteger(int signum,byte[] magnitude)将 BigInteger 的符号-数量表⽰形式转换为 BigInteger。
* 该符号表⽰为⼀个正负号整数值:-1 表⽰负,0 表⽰零,1 表⽰正。
* 该⼤⼩是⼀个 big-endian 字节顺序的 byte 数组:最⾼有效字节在第零个元素中。
* 允许零长度数量数组,这会导致 BigInteger 的值为 0,⽆论其正负号是 -1、0 还是 1。bigdecimal转换为integer
* 参数:
* signum - 该数的正负号(-1 表⽰负,0 表⽰零,1 表⽰正)。
* magnitude - 该数的⼤⼩的 big-endian ⼆进制表⽰形式。
* 抛出:
* NumberFormatException - signum 不是三个合法值之⼀(-1、0 和 1),或者 signum 是 0 并且 magnitude 包含⼀个或多个⾮零字节。
*
* String(to)  to要转换成的进制
*
* public String toString(int radix)返回此 BigInteger 的给定基数的字符串表⽰形式。
* 如果该基数超出从 Character.MIN_RADIX 到 Character.MAX_RADIX(包括)这⼀范围,则其默认值为 10(String 就是这种情况)。
* 使⽤由 Character.forDigit 提供的从数字到字符的映射,并在需要时在前⾯加⼀个负号。(此表⽰形式与 (String, int) 构造⽅法兼容。)
* 参数:
* radix - 字符串表⽰形式的基数。
* 返回:
* 此 BigInteger 给定基数的字符串表⽰形式。
*/
String md5code = new BigInteger(1, digest).toString(16);
//如果加密后的md5密⽂不⾜32位,前⾯补0
while (true){
if (md5code.length()<32){
md5code = "0" + md5code;
}else {
break;
}
}
return md5code;
} catch (Exception e) {
/
/不到md5算法,或者加密过程出现异常
e.printStackTrace();
}
//出现异常,返回空
return null;
}
2.使⽤HexString()进⾏转换
public static String md5Encrypt2(String src){
try {
//获取md5算法
MessageDigest md5Digest = Instance("md5");
/
/将要加密的字符串转为byte数组进⾏加密
byte[] digest = md5Digest.Bytes("utf-8"));
//将加密后的byte数组转换成⼗六进制字符串
StringBuilder sb = new StringBuilder();
for (int i = 0; i < digest.length; ++i) {
/*String s = HexString(digest[i] & 0xFF);
//保证全部为两位,最后结果为32位
if (s.length() == 1){
sb.append("0");
}*/
/**
* 为了显⽰⼀个byte型的单字节⼗六进制(两位⼗六进制表⽰)的编码,请使⽤:
* HexString((byteVar & 0x000000FF) | 0xFFFFFF00).substring(6)
* byteVar & 0x000000FF的作⽤是,如果byteVar 是负数,则会清除前⾯24个零,正的byte整型不受影响。
* (...) | 0xFFFFFF00的作⽤是,如果byteVar 是正数,则置前24位为⼀,这样toHexString输出⼀个⼩于等于15的byte整型的⼗六进制时,                * 倒数第⼆位为零且不会被丢弃,这样可以通过substring⽅法进⾏截取最后两位即可。
*/
String s = HexString((digest[i] & 0x000000FF) | 0xFFFFFF00).substring(6);
sb.append(s);
}
String();
} catch (Exception e) {
//不到md5算法,或者加密过程出现异常
e.printStackTrace();
}
//出现异常,返回空
return null;
}
3.第三种,⼿动实现进制转换
//16进制数字数组
private final static String[] hexDigits = {"0", "1", "2", "3", "4", "5", "6", "7",
"8", "9", "a", "b", "c", "d", "e", "f"};
/
/将byte数组转换成16进制字符串
public static String byteArrayToHexString(byte[] b) {
StringBuilder resultSb = new StringBuilder();
for (byte aB : b) {
resultSb.append(byteToHexString(aB));
}
String();
}
//将byte转为16进制字符串
private static String byteToHexString(byte b) {
int n = b;
if (n < 0) {
n = 256 + n;
}
int d1 = n / 16;
int d2 = n % 16;
return hexDigits[d1] + hexDigits[d2];
}
public static String md5Encrypt3(String src){
String resultString = null;
try {
resultString = src;
/
/获取md5算法
MessageDigest md = Instance("MD5");
//对字符串进⾏加密,并转换成16进制字符串
resultString = byteArrayToHexString(md.Bytes()));
} catch (Exception e) {
e.printStackTrace();
}
return resultString;
}
//可以选择指定编码
public static String md5Encrypt4(String src, String charsetname){
String resultString = null;
try {
resultString = src;
MessageDigest md = Instance("MD5");
if (charsetname == null || "".equals(charsetname)){
resultString = byteArrayToHexString(md.Bytes()));
} else {
resultString = byteArrayToHexString(md.Bytes(charsetname)));
}
} catch (Exception e) {
e.printStackTrace();
}
return resultString;
}
4.使⽤apache⼯具类进⾏转换
public static String md5Encrypt5(String src){
String resultString = null;
try {
MessageDigest md5 = Instance("MD5");
byte[] bytes = md5.Bytes("utf-8"));
resultString = deHexString(bytes);
} catch (Exception e) {
e.printStackTrace();
}
return resultString;
}
Apache转换源码:
protected static char[] encodeHex(final byte[] data, final char[] toDigits) {
final int l = data.length;
final char[] out = new char[l << 1];
// two characters form the hex value.
for (int i = 0, j = 0; i < l; i++) {
out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
out[j++] = toDigits[0x0F & data[i]];
}
return out;
}
5.测试代码
public static void main(String[] args) {
String md5Encrypt = md5Encrypt("shaoyuanhu");
System.out.println(md5Encrypt);
System.out.println(md5Encrypt.length());
String md5Encrypt2 = md5Encrypt2("shaoyuanhu");
System.out.println(md5Encrypt2);
System.out.println(md5Encrypt2.length());
String md5Encrypt3 = md5Encrypt3("shaoyuanhu");
System.out.println(md5Encrypt3);
System.out.println(md5Encrypt3.length());
String md5Encrypt4 = md5Encrypt4("shaoyuanhu",null);
System.out.println(md5Encrypt4);
System.out.println(md5Encrypt4.length());
String md5Encrypt5 = md5Encrypt5("shaoyuanhu");
System.out.println(md5Encrypt5);
System.out.println(md5Encrypt5.length());
}
6.关于byte&0xFF的原因,请参考

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。