如何调用哈希算法,特别是使用位移0xff?

时间:2011-07-24 18:43:02

标签: java security jaas

以下代码片段源自Core Java Vol 2(第7版),展示了如何使用Java创建SHA1和MD5指纹。

事实证明,唯一有效的功能是从文本文件中加载明文。

MessageDigestFrame.computeDigest()如何计算指纹,特别是使用位移模式(第171-172行)?

public void computeDigest(byte[] b)
{  
  currentAlgorithm.reset();
  currentAlgorithm.update(b);
  byte[] hash = currentAlgorithm.digest();
  String d = "";
  for (int i = 0; i < hash.length; i++)
  {  
     int v = hash[i] & 0xFF;
     if (v < 16) d += "0";
     d += Integer.toString(v, 16).toUpperCase() + " ";
  }
  digest.setText(d);
} 

3 个答案:

答案 0 :(得分:2)

无论你给它什么方法都应该正常工作 - 如果你得到错误的结果,我怀疑你正在加载错误的文件。请显示该代码,我们可以帮助您解决出错的问题。

就代码而言,这一行:

int v = hash[i] & 0xFF;

基本上用于将字节视为无符号。字节用Java签名 - 这是语言中公认的设计错误 - 但我们希望打印出十六进制值,就好像它是无符号整数一样。只有最后8位的按位AND有效地将其转换为被视为无符号的字节的整数值。

(有更好的方法将字节数组转换为十六进制字符串,但这是另一回事。)

答案 1 :(得分:1)

它不是位移位,而是位屏蔽。 hash[i]是一个字节。当它被加宽到整数时,你需要屏蔽掉更高的整数位,因为可能有符号扩展。

byte b = (byte)0xEF;
System.out.println("No masking: " + (int)b);
System.out.println("Masking:    " + (int)(b & 0xFF));

答案 2 :(得分:0)

这剪了一下:

 int v = hash[i] & 0xFF;
 if (v < 16) d += "0";
 d += Integer.toString(v, 16).toUpperCase() + " ";

首先将v的最低8位设置为0(因为0xFF是二进制的11111111)。 然后,如果结果数字只是十六进制的一位数(<16),则添加前导“0”。 最后将结果转换为十六进制并将其添加到字符串中。