您的位置:首页 > 理论基础

三年六班的李子明同学,你妈拿了两本计算机基础在二号树上等你

2015-05-20 16:31 155 查看


MessageDigest.getInstance("md5")


初始化,用

MessageDigest.digest(byte[] input)


方法执行MD5加密,返回的结果也是个byte数组。

然后把数组中每一个字节转换成两位的十六进制字符串,如果结果只有一位的话在前面添零补位。

结果就是一个30位长度的MD5字符串了。

/** 对数据作MD5加密。 */
public static String hashUp(String src) {
String hash = null;

try {
byte[] md5 = MessageDigest.getInstance("md5").digest(src.getBytes());

StringBuilder builder = new StringBuilder();
for (byte b : md5) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) {
builder.append('0');
}

builder.append(hex);
}
hash = builder.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}

return hash;
}


但是!重点是!

为什么要用0xff来与一下b呢?

因为不这样处理的话b是正数还不要紧,是负数的话结果就不对了。

首先假设MD5结果中某一位是26,byte类型长8位,二进制形式是:

0001 1010

因为toHexString方法需要的参数是int类型,所以要把b强转成int,变成了32位,于是前24位填零补位,二进制形式是:

0000 0000 0000 0000 0000 0000 0001 1010

把参数转成十六进制,结果是:

0000001A

前面的0全部省略,结果是1A,没有问题。

但是这某一位变成了-26会怎么样呢?

负数在计算机中用正数的补码形式存储,于是把26的二进制值每一位取反再加一,结果是:

1110 0110

于是再把它强转为32位,也就是26的补码。这一转不要紧,结果成了:

1111 1111 1111 1111 1111 1111 1110 0110

蔚为大观。

这个时候再四位一转,把它转成十六进制,结果就是:

FFFFFFE6

符号变了一下,结果变得妈都不认识了。

虽然结果好像没什么问题,但是前面的一堆F可不打算直接拿来用。

于是干脆一了百了,把int值的前24位都扔了不要,用0xff,也就是:

0000 0000 0000 0000 0000 0000 1111 1111

与上它:

1111 1111 1111 1111 1111 1111 1110 0110

前24位当场就没了,真是太惨了:

0000 0000 0000 0000 0000 0000 1110 0110

这时候再转成十六进制,结果是E6,虽然跟开始的值不一样,

……

…………

但是反正也没人在乎……
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: