输出到文件然后输入后,散列中的字符串不再相同

这是一个奇怪的事情,已经花了我一整天:

如果将一个简单的字符串(如“1”)写入文件并立即读取,则获取的字符串equals原始字符串。

但是如果String是由某个哈希函数生成的,则获取的String 不再相同

以下代码打印true false ,我想知道场景背后的技巧。

非常感谢你。

 public static void main(String[] args) { try { String s1 = "1"; File f1 = new File("f1"); write (s1, f1); System.out.println(read(f1).equals(s1)); MessageDigest md = MessageDigest.getInstance("SHA-512"); String s2 = foo(new File("1.jpg"), md); File f2 = new File("f2"); write (s2, f2); System.out.println(read(f2).equals(s2)); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } // Hash f by md static String foo (File f, MessageDigest md) throws IOException { FileInputStream fis = new FileInputStream(f); DigestInputStream dis = new DigestInputStream(fis, md); byte[] b = new byte[1024]; while (dis.read(b, 0, 1024) != -1) { } md = dis.getMessageDigest(); String s = new String(md.digest()); dis.close(); fis.close(); return s; } static void write (String s, File f) throws IOException { FileWriter fw = new FileWriter(f); BufferedWriter bw = new BufferedWriter(fw); bw.write(s); bw.newLine(); bw.close(); fw.close(); } static String read (File f) throws IOException { FileReader fr = new FileReader(f); BufferedReader bf = new BufferedReader(fr); String s; s = bf.readLine(); bf.close(); fr.close(); return s; } 

这是你的第一个问题:

 String s = new String(md.digest()); 

您正在使用平台默认编码创建包含任意二进制数据的字符串。 它可能不是平台默认编码中的有效文本数据。 换句话说,你正在丢失数据。 使用base-64对其进行编码 – 这样您将始终拥有一个包含ASCII字符的字符串,并且可以可靠地返回原始二进制数据。

您的第二个常见问题是使用FileReaderFileWriter 。 这些总是使用默认的平台编码,这是一个糟糕的 API决定,因为它在我看来几乎没用。 您应该几乎总是指定编码 – 我倾向于使用UTF-8。 使用FileInputStream / FileOutputStreamInputStreamReader / InputStreamWriter来读取/写入带有文件的文本。 (或者使用Guava帮助程序。)

散列文件的摘要值很可能包含换行符或换行符(0x10或0x13),这会破坏您使用BufferedReader.readLine()读取字符串的方式。