Java MessageDigest SHA1 结果与原始哈希值的字节数组比较?
Java byte array comparison of MessageDigest SHA1 result and original hash value?
我想比较两个字节数组。一种是用MessageDigest
SHA1从明文计算出来的,另一种是字节数组中的十六进制本身,没有计算。
MessageDigest
returns 20 字节长的结果,String.getBytes()
returns 40 字节长的数组。 bytesToHex()
功能与 this answer 中提供的功能相同,仅用于打印。
问题:
如何在不增加额外开销的情况下将字符串转换为字节数组(然后与使用 MessageDigest
计算的结果进行比较)? bytesToHex()
和 .toUppercase()
的字符串比较有效,但不是一个选项,因为速度在应用程序中至关重要。
代码:
MessageDigest md;
try {
md = MessageDigest.getInstance("SHA-1");
byte[] toEncode = "test".getBytes();
byte[] encoded = md.digest(toEncode);
System.out.println("String to encode:\t\t" + new String(toEncode));
System.out.println("Encoded in hex:\t\t\t" + bytesToHex(encoded));
System.out.println("Encoded length:\t\t\t" + encoded.length);
byte[] hash = new String("a94a8fe5ccb19ba61c4c0873d391e987982fbbd3").getBytes(); // "test" representation in SHA1
System.out.println("\nHash to compare with:\t\t" + new String(hash));
System.out.println("Hash length:\t\t\t" + hash.length);
System.out.println("Two byte array equals:\t\t" + Arrays.equals(hash, encoded));
System.out.println("Two equals in string:\t\t" + new String(hash).equals(bytesToHex(encoded).toLowerCase()));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
结果:
String to encode: test
Encoded in hex: A94A8FE5CCB19BA61C4C0873D391E987982FBBD3
Encoded length: 20
Hash to compare with: a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
Hash length: 40
Two byte array equals: false
Two equals in string: true
您没有将十六进制表示解码为字节。如果您愿意,例如使用来自 this answer 的解决方案,则两个数组将匹配:
try {
byte[] encoded = MessageDigest.getInstance("SHA-1").digest("test".getBytes());
byte[] hash = DatatypeConverter.parseHexBinary("a94a8fe5ccb19ba61c4c0873d391e987982fbbd3");
System.out.println("Two byte array equals:\t\t" + Arrays.equals(hash, encoded));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
我想比较两个字节数组。一种是用MessageDigest
SHA1从明文计算出来的,另一种是字节数组中的十六进制本身,没有计算。
MessageDigest
returns 20 字节长的结果,String.getBytes()
returns 40 字节长的数组。 bytesToHex()
功能与 this answer 中提供的功能相同,仅用于打印。
问题:
如何在不增加额外开销的情况下将字符串转换为字节数组(然后与使用 MessageDigest
计算的结果进行比较)? bytesToHex()
和 .toUppercase()
的字符串比较有效,但不是一个选项,因为速度在应用程序中至关重要。
代码:
MessageDigest md;
try {
md = MessageDigest.getInstance("SHA-1");
byte[] toEncode = "test".getBytes();
byte[] encoded = md.digest(toEncode);
System.out.println("String to encode:\t\t" + new String(toEncode));
System.out.println("Encoded in hex:\t\t\t" + bytesToHex(encoded));
System.out.println("Encoded length:\t\t\t" + encoded.length);
byte[] hash = new String("a94a8fe5ccb19ba61c4c0873d391e987982fbbd3").getBytes(); // "test" representation in SHA1
System.out.println("\nHash to compare with:\t\t" + new String(hash));
System.out.println("Hash length:\t\t\t" + hash.length);
System.out.println("Two byte array equals:\t\t" + Arrays.equals(hash, encoded));
System.out.println("Two equals in string:\t\t" + new String(hash).equals(bytesToHex(encoded).toLowerCase()));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
结果:
String to encode: test
Encoded in hex: A94A8FE5CCB19BA61C4C0873D391E987982FBBD3
Encoded length: 20
Hash to compare with: a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
Hash length: 40
Two byte array equals: false
Two equals in string: true
您没有将十六进制表示解码为字节。如果您愿意,例如使用来自 this answer 的解决方案,则两个数组将匹配:
try {
byte[] encoded = MessageDigest.getInstance("SHA-1").digest("test".getBytes());
byte[] hash = DatatypeConverter.parseHexBinary("a94a8fe5ccb19ba61c4c0873d391e987982fbbd3");
System.out.println("Two byte array equals:\t\t" + Arrays.equals(hash, encoded));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}