什么和& 0xff和MD5结构?

时间:2014-09-14 22:07:07

标签: java 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));

每个部分在这个结构中做了什么????

谢谢,我很抱歉因为我不喜欢Java。

2 个答案:

答案 0 :(得分:6)

据推测,大部分代码都是明确的,这里唯一的谜是这个表达式:

(bytes[i] & 0xff) + 0x100

第一部分:

bytes[i] & 0xff

将位置i处的字节扩展为int值,位位置为8-31,零。在Java中,byte数据类型是有符号整数值,因此扩展符号扩展了该值。如果没有& 0xff,大于0x7f的值将最终为负int值。其余的是相当明显的:它增加了0x100,它只是打开索引8处的位(因为它在(bytes[i] & 0xff)中保证为0。然后由...转换为十六进制String值致电Integer.toString(..., 16)

首先添加0x100然后剥离1(由substring(1)调用完成,从位置1开始到结束)的原因是保证最终结果中有两个十六进制数字。否则,低于0x10的字节值在转换为十六进制时将最终成为一个字符的字符串。

这是否具有争议性是否所有表现更好(当然不是更清晰):

sb.append(String.format("%02x", bytes[i]));

答案 1 :(得分:4)

翻译成十六进制字符串是一种非常混乱的方式。

  • & 0xFF执行二进制AND,导致返回值介于0和255之间(无论如何总是一个字节)
  • + 0x100在结果中添加256以确保结果始终为3位
  • Integer.toString(src, 16)将整数转换为带有螺旋16(十六进制)
  • 的字符串
  • 最后.substring(1)删除第一个字符(第2步中的1

因此,这是一种将字节转换为始终为2个字符的十六进制字符串的非常精细和混淆的方法。