&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

加宽在位置字节iint的比特位置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]));