Java 散列中的字符串在输出到文件然后输入后不再相同
这是一件让我花了整整一天时间的奇怪事情: 如果用户将一个简单的字符串(如“1”)写入文件并立即读取,则获取的字符串Java 散列中的字符串在输出到文件然后输入后不再相同,java,Java,这是一件让我花了整整一天时间的奇怪事情: 如果用户将一个简单的字符串(如“1”)写入文件并立即读取,则获取的字符串等于原始字符串 但是,如果字符串是由某个哈希函数生成的,则获取的字符串将不再相同 下面的代码打印出true-false,我想知道幕后的诀窍 多谢各位 public static void main(String[] args) { try { String s1 = "1"; File f1 = new File("f1");
等于原始字符串
但是,如果字符串是由某个哈希函数生成的,则获取的字符串将不再相同
下面的代码打印出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;
}
publicstaticvoidmain(字符串[]args){
试一试{
字符串s1=“1”;
文件f1=新文件(“f1”);
写入(s1,f1);
System.out.println(读取(f1).等于(s1));
MessageDigest md=MessageDigest.getInstance(“SHA-512”);
字符串s2=foo(新文件(“1.jpg”),md);
文件f2=新文件(“f2”);
写入(s2,f2);
System.out.println(读取(f2).等于(s2));
}捕获(无算法异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
//通过md散列f
静态字符串foo(文件f,MessageDigest md)引发IOException{
FileInputStream fis=新的FileInputStream(f);
DigestInputStream dis=新的DigestInputStream(fis,md);
字节[]b=新字节[1024];
while(dis.read(b,0,1024)!=-1){
}
md=dis.getMessageDigest();
字符串s=新字符串(md.digest());
dis.close();
fis.close();
返回s;
}
静态无效写入(字符串s、文件f)引发IOException{
FileWriter fw=新的FileWriter(f);
BufferedWriter bw=新的BufferedWriter(fw);
bw.写入;
换行符();
bw.close();
fw.close();
}
静态字符串读取(文件f)引发IOException{
FileReader fr=新的FileReader(f);
BufferedReader bf=新的BufferedReader(fr);
字符串s;
s=bf.readLine();
bf.close();
fr.close();
返回s;
}
这是您的第一个问题:
String s = new String(md.digest());
您正在使用平台默认编码创建包含任意二进制数据的字符串。在平台默认编码中,它可能不是有效的文本数据。换句话说,您正在丢失数据。改为使用base-64编码-这样您将始终拥有一个包含ASCII字符的字符串,并且可以可靠地返回原始二进制数据
第二个常见问题是使用FileReader
和FileWriter
。它们总是使用默认的平台编码,这是一个可怕的API决策,因为在我看来,这使它们几乎毫无用处。您几乎应该总是指定一种编码——我倾向于使用UTF-8。使用FileInputStream
/FileOutputStream
和InputStreamReader
/InputStreamWriter
读取/写入包含文件的文本。(或使用番石榴助手例程。)这是您的第一个问题:
String s = new String(md.digest());
您正在使用平台默认编码创建包含任意二进制数据的字符串。在平台默认编码中,它可能不是有效的文本数据。换句话说,您正在丢失数据。改为使用base-64编码-这样您将始终拥有一个包含ASCII字符的字符串,并且可以可靠地返回原始二进制数据
第二个常见问题是使用FileReader
和FileWriter
。它们总是使用默认的平台编码,这是一个可怕的API决策,因为在我看来,这使它们几乎毫无用处。您几乎应该总是指定一种编码——我倾向于使用UTF-8。使用FileInputStream
/FileOutputStream
和InputStreamReader
/InputStreamWriter
读取/写入包含文件的文本。(或使用Guava helper例程。)哈希文件的摘要值很可能包含换行符或换行符(0x10或0x13),这会中断您使用BufferedReader.readLine()读取字符串的方式。哈希文件的摘要值很可能包含换行符或换行符(0x10或0x13)这打破了您使用BufferedReader.readLine()
读取字符串的方式。我想试试这个。谢谢。我想试试这个。谢谢。我认为这不是问题所在。在调试模式下,这两个字符串看起来是一样的,至少在我的特定情况下是一样的。谢谢。我认为这不是问题所在。在调试模式下,这两个字符串看起来是一样的,至少在我的特定情况下是一样的。非常感谢。