【问题标题】:SHA Hashing behaving unexpectedly in Java - Code ProvidedSHA Hashing 在 Java 中的行为异常 - 提供的代码
【发布时间】:2015-11-15 04:39:23
【问题描述】:

读入一个文件,然后使用 SHA-256 对其进行哈希处理,我发现了一个 tutorial,它显示了两种不同的方法。

当比较我散列的文件(这是一个 PDF) 与这两种方法时,它们不匹配。我正确地遵循代码,不明白为什么它不匹配。

这是我的结果:

十六进制格式: b050692edb134da209adf76347f6c5e49db8734edeaa44876606ec8e5559ab4e 十六进制格式: b050692edb134da29adf76347f6c5e49db8734edeaa4487666ec8e5559ab4e

好像把中间的两个零去掉了,我就是不明白为什么

Java 代码

import java.io.FileInputStream;
import java.security.MessageDigest;

public class SHAHash{
   public static void main(String[] args)throws Exception{
      MessageDigest md = MessageDigest.getInstance("SHA-256");
      FileInputStream fis = new FileInputStream("myfile");

      byte[] dataBytes = new byte[1024];
      int nread = 0;
      while((nread = fis.read(dataBytes))!= -1){
         md.update(dataBytes, 0, nread);
      };

      byte[] mdbytes = md.digest();

      StringBuffer sb1 = new StringBuffer();
      for(int i = 0; i < mdbytes.length; i++){
        sb1.append(Integer.toString((mdbytes[i] & 0xFF) + 0x100, 16).substring(1));
      }
      System.out.println("Hex format: " + sb1.toString());

      StringBuffer sb2 = new StringBuffer();
      for(int i = 0; i < mdbytes.length; i++){
         sb2.append(Integer.toHexString(0xFF & mdbytes[i]));
      }
      System.out.println("Hex format: " + sb2.toString());
   }
}

【问题讨论】:

  • 请不要使用StringBuffer,您缺少前导0(s) 的值。

标签: java hash sha256


【解决方案1】:

您应该使用StringBuilder 而不是StringBuffer(方法不同步,并且您没有使用多个线程,这就像VectorArrayList 之间的区别)。此外,您需要保留前导 0(s)。你可以用String.format(String, Object...) 之类的东西来纠正你的第二个循环。把它们放在一起,

StringBuilder sb2 = new StringBuilder();
for (int i = 0; i < mdbytes.length; i++) {
    sb2.append(String.format("%02x", 0xFF & mdbytes[i]));
}
System.out.println("Hex format: " + sb2.toString());

【讨论】:

  • 这就是我要说的。感谢您的解释。让我进行更改,我会接受您的回答。
  • 这行得通,你对十六进制的格式是正确的。我想如果我遍历每个十六进制值,答案就会在我面前突然出现。
  • @milk 您可能还想阅读this answerthis answer或者只使用Apache Commons CodecHex
【解决方案2】:

两者的区别是先加0x100,然后只取一个子串。

这样,第一个循环中的toString 调用总是返回一个以1 开头的字符串,后跟实际值。这样零就被保留了。

第二个循环产生错误的输出,因为零位丢失了。

【讨论】:

  • 我明白了,这很有意义。我不完全明白他为什么这样做。您的解释确实澄清了这一点。谢谢你。我通过使用字符串格式化程序完成了@ElliotFrisch 的建议。我想作为一个被解析的整数,我不确定为什么我希望前导零保留。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-07
  • 1970-01-01
  • 1970-01-01
  • 2020-05-28
相关资源
最近更新 更多