Java SHA 未唤醒。哈希值不等于字符串。我的编码有问题吗?
Java SHA not woking. Hash value dosen't equal String. Is there an issue with my encoding?
基本上我都有这个
if (args.length != 1) {
System.err.println("Usage: java MyMd5 <message>");
System.exit(1);
}
try {
// get message
byte[] message = args[0].getBytes("UTF8");
// create message digest object for MD5
MessageDigest messageDigest = MessageDigest.getInstance("SHA");
// System.out.println("Provider: " +
messageDigest.getProvider().getInfo();
// create message digest
messageDigest.update(message);
byte[] md = messageDigest.digest();
// print result
System.out.println("Message Digest Algorithm: MD5");
System.out.println("Message: " + new String(message));
System.out.println("Message Digest: \"" + new String(md, "UTF8") + "\"");
String HashPassword=new String(md, "UTF8");
System.out.println(HashPassword);
System.out.println(HashPassword.equals("???8p???W?B:??N?~"));
但不知何故,当我尝试比较它时,它返回 false。我的编码有问题吗?谢谢!
Message Digest Algorithm: MD5
Message: pass123
Message Digest: "???8p???W?B:??N?~"
???8p???W?B:??N?~
false
问题在于不必要的编码,使用 md5 我们必须以正确的方式对字符串进行编码,而不是使用 UTF8 编码
public static void main(String[] args) throws Exception {
String pass = "pass123";
byte[] message = pass.getBytes();
MessageDigest messageDigest = MessageDigest.getInstance("SHA");
messageDigest.update(message);
byte[] md = messageDigest.digest();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < md.length; i++) {
sb.append(Integer.toString((md[i] & 0xff) + 0x100, 16).substring(1));
}
System.out.println("encoded pass:" + sb.toString());
System.out.println(sb.toString().equals("aafdc23870ecbcd3d557b6423a8982134e17927e"));
}
如果我正确理解了你的问题,你想将新生成的散列字符串与现有散列字符串(存储在数据库或其他地方)进行比较。上面提供的代码是可能的,如果您将生成的值(而不是从控制台复制)存储到数据库中,然后将其与新生成的值进行比较,您将得到 true
。
但是当您生成散列时,它包含符号(字符),在任何字符串编码中都没有正确的表示。所以,没有人不将散列存储为纯字符串。通常它们存储在 hex string
表示或 Base64
表示中。
使用下面提供的 hex strings
实现:
public static void main(String[] args) throws Exception { // args = ["Hello world"]
if (args.length != 1) {
System.err.println("Usage: java MyMd5 <message>");
System.exit(1);
}
// get message
byte[] message = args[0].getBytes("UTF8"); //You may have problems with encoding here. In Windows, for example, with symbols that are out of English alphabet range
// create message digest object for MD5
MessageDigest messageDigest = MessageDigest.getInstance("SHA");
// System.out.println("Provider: " +
messageDigest.getProvider().getInfo();
// create message digest
messageDigest.update(message);
byte[] md = messageDigest.digest();
System.out.println("Digest: " + byteArrayToHexString(md));
System.out.println("Is equals? " + byteArrayToHexString(md).equals("7b502c3a1f48c8609ae212cdfb639dee39673f5e"));
}
private static String byteArrayToHexString(byte[] array) {
StringBuilder result = new StringBuilder(array.length);
IntStream.range(0, array.length)
.forEach(i -> result.append(Integer.toString( (array[i] & 0xff) + 0x100, 16).substring(1)));
return result.toString();
}
此外,在提供的示例中提到您正在使用 MD5
,但实际上它是 SHA
。 MessageDigest messageDigest = MessageDigest.getInstance("SHA");
基本上我都有这个
if (args.length != 1) {
System.err.println("Usage: java MyMd5 <message>");
System.exit(1);
}
try {
// get message
byte[] message = args[0].getBytes("UTF8");
// create message digest object for MD5
MessageDigest messageDigest = MessageDigest.getInstance("SHA");
// System.out.println("Provider: " +
messageDigest.getProvider().getInfo();
// create message digest
messageDigest.update(message);
byte[] md = messageDigest.digest();
// print result
System.out.println("Message Digest Algorithm: MD5");
System.out.println("Message: " + new String(message));
System.out.println("Message Digest: \"" + new String(md, "UTF8") + "\"");
String HashPassword=new String(md, "UTF8");
System.out.println(HashPassword);
System.out.println(HashPassword.equals("???8p???W?B:??N?~"));
但不知何故,当我尝试比较它时,它返回 false。我的编码有问题吗?谢谢!
Message Digest Algorithm: MD5
Message: pass123
Message Digest: "???8p???W?B:??N?~"
???8p???W?B:??N?~
false
问题在于不必要的编码,使用 md5 我们必须以正确的方式对字符串进行编码,而不是使用 UTF8 编码
public static void main(String[] args) throws Exception {
String pass = "pass123";
byte[] message = pass.getBytes();
MessageDigest messageDigest = MessageDigest.getInstance("SHA");
messageDigest.update(message);
byte[] md = messageDigest.digest();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < md.length; i++) {
sb.append(Integer.toString((md[i] & 0xff) + 0x100, 16).substring(1));
}
System.out.println("encoded pass:" + sb.toString());
System.out.println(sb.toString().equals("aafdc23870ecbcd3d557b6423a8982134e17927e"));
}
如果我正确理解了你的问题,你想将新生成的散列字符串与现有散列字符串(存储在数据库或其他地方)进行比较。上面提供的代码是可能的,如果您将生成的值(而不是从控制台复制)存储到数据库中,然后将其与新生成的值进行比较,您将得到 true
。
但是当您生成散列时,它包含符号(字符),在任何字符串编码中都没有正确的表示。所以,没有人不将散列存储为纯字符串。通常它们存储在 hex string
表示或 Base64
表示中。
使用下面提供的 hex strings
实现:
public static void main(String[] args) throws Exception { // args = ["Hello world"]
if (args.length != 1) {
System.err.println("Usage: java MyMd5 <message>");
System.exit(1);
}
// get message
byte[] message = args[0].getBytes("UTF8"); //You may have problems with encoding here. In Windows, for example, with symbols that are out of English alphabet range
// create message digest object for MD5
MessageDigest messageDigest = MessageDigest.getInstance("SHA");
// System.out.println("Provider: " +
messageDigest.getProvider().getInfo();
// create message digest
messageDigest.update(message);
byte[] md = messageDigest.digest();
System.out.println("Digest: " + byteArrayToHexString(md));
System.out.println("Is equals? " + byteArrayToHexString(md).equals("7b502c3a1f48c8609ae212cdfb639dee39673f5e"));
}
private static String byteArrayToHexString(byte[] array) {
StringBuilder result = new StringBuilder(array.length);
IntStream.range(0, array.length)
.forEach(i -> result.append(Integer.toString( (array[i] & 0xff) + 0x100, 16).substring(1)));
return result.toString();
}
此外,在提供的示例中提到您正在使用 MD5
,但实际上它是 SHA
。 MessageDigest messageDigest = MessageDigest.getInstance("SHA");