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

发布于 2024-11-26 08:29:08 字数 562 浏览 3 评论 0原文

以下代码片段源自 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);
} 

The following code snippet, sourced from Core Java Vol 2 (7th Ed), shows how to create an SHA1 and an MD5 fingerprint using Java.

It turns out that the only function that works is when I load the cleartext from a textfile.

How does MessageDigestFrame.computeDigest() work out the fingerprint, and, particularly the use of the bit shifting pattern (Line 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);
} 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

格子衫的從容 2024-12-03 08:29:08

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

就代码而言,这一行:

int v = hash[i] & 0xFF;

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

(有更好的方法将字节数组转换为十六进制字符串,但这是一个单独的问题。)

The method should work fine whatever you give it - if you're getting the wrong results, I suspect you're loading the file incorrectly. Please show that code, and we can help you work out what's going wrong.

In terms of the code, this line:

int v = hash[i] & 0xFF;

is basically used to treat a byte as unsigned. Bytes are signed in Java - an acknowledged design mistake in the language - but we want to print out the hex value as if it were an unsigned integer. The bitwise AND with just the bottom 8 bits effectively converts it to the integer value of the byte treated as unsigned.

(There are better ways to convert a byte array to a hex string, but that's a separate matter.)

不即不离 2024-12-03 08:29:08

它不是位移位,而是位掩码。 hash[i] 是一个字节。当它扩展为整数时,由于可能的符号扩展,您需要屏蔽较高的整数位。

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

It is not bit shifting, it is bit masking. hash[i] is a byte. When it is widened to integer you need to mask off the higher integer bits because of possible sign extension.

byte b = (byte)0xEF;
System.out.println("No masking: " + (int)b);
System.out.println("Masking:    " + (int)(b & 0xFF));
楠木可依 2024-12-03 08:29:08

这被剪断了:

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

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

This snipped:

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

First you set all but the lowest 8 bits of v to 0 (because 0xFF is 11111111 in binary).
Then if the resulting number is only one digit in hex (< 16) you add a leading "0".
Finally convert the result to hex and add it to the string.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文