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

Dan*_*ode 0 java

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

如果将一个简单的字符串(如"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 <i>f</i> by <i>md</i>
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;
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 6

这是你的第一个问题:

String s = new String(md.digest());
Run Code Online (Sandbox Code Playgroud)

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

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