&0xff和MD5分别做什么?
问题内容:
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class JavaMD5 {
public static void main(String[] args) {
String passwordToHash = "MyPassword123";
String generatedPassword = null;
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(passwordToHash.getBytes());
byte[] bytes = md.digest();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
}
generatedPassword = sb.toString();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(generatedPassword);
}
}
这行是问题所在:
sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
每个部分在此结构中起什么作用????
谢谢,我很抱歉询问Beacuse,因为我是Java新手。
问题答案:
大概大多数代码都是清晰的,这里唯一让您感到困惑的是此表达式:
(bytes[i] & 0xff) + 0x100
第一部分:
bytes[i] & 0xff
加宽在位置字节i
到int
的比特位置8-31用零值。在Java中,byte
数据类型是带符号的整数值,因此加宽的符号会扩展该值。如果没有& 0xff
,则大于0x7f的值最终将变为负值int
。剩下的就很明显了:它添加了0x100,它只是打开了索引8的位(因为它保证为0 in
(bytes[i] & 0xff)
。然后String
通过调用转换为十六进制值)Integer.toString(..., 16)
。
首先添加0x100,然后剥离1(通过substring(1)
调用完成,它将子字符串从位置1到末尾开始)的原因是为了保证最终结果中的两个十六进制数字。否则,转换为十六进制时,低于0x10的字节值将以一个字符的字符串结尾。
是否所有性能都比以下更好(尚不清楚)尚有争议:
sb.append(String.format("%02x", bytes[i]));