&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) 。然后通过调用将其转换为hexString值to Integer.toString(..., 16)

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

所有这些都具有更好的性能(当然不是更清晰)是有争议的:

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

翻译成hex字符串是一种非常混乱的方式。

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

因此,这是将字节转换为始终为2个字符的hex字符串的非常精细和混淆的方式。