英文:
sha512 string generated is different from string generated in java
问题
我正在尝试生成一个类似于Java代码生成的哈希值,以便稍后在数据库中进行重复检查时可以进行比较。
这是Java代码生成哈希值的方式:
public String getHash(String algorithm, String message, String salt) throws NoSuchAlgorithmException {
// Create MessageDigest instance for given algorithm
MessageDigest md = MessageDigest.getInstance("SHA-512");
md.update(salt.getBytes());
byte[] bytes = md.digest(message.getBytes());
// Convert it to hexadecimal format
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16)
.substring(1));
}
return sb.toString();
}
这是我用Go语言编写的代码:
func HashSha512(original string) (string, error) {
salt := "abcde687869"
originalStrBytes := []byte(original)
sha512Hasher := sha512.New()
saltedValueBytes := append(originalStrBytes, []byte(salt)...)
sha512Hasher.Write(saltedValueBytes)
hashedBytes := sha512Hasher.Sum(nil)
s := ""
var x uint64 = 0x100
y := byte(x)
for i := 0; i < len(hashedBytes); i++ {
s += fmt.Sprintf("%x", ((hashedBytes[i] & 0xff) + y))[1:]
}
return s, nil
}
但是生成的字符串不相同。
Go Playground链接:https://play.golang.com/p/uXaw7y2tklN
在Go中生成的字符串是:
99461a225184c478b8398c7f0dcc1d3afed107660d08a7282a10f5e2ab6
而在Java中生成的字符串是:
020e93364e5186b7d4ac211cd116425234937d390fcc4e1c554fa1e4bafcb934493047ab841e06f00aa28aabee43b737a6bae2f3fc52e431dde724e691aa952d
我做错了什么?
英文:
I am trying to generate a hash similar to one generated in java code so that they can be compared to check for duplicates later in database.
This is how the java code generates it:
public String getHash(String algorithm, String message, String salt) throws NoSuchAlgorithmException {
// Create MessageDigest instance for given algorithm
MessageDigest md = MessageDigest.getInstance("SHA-512");
md.update(salt.getBytes());
byte[] bytes = md.digest(message.getBytes());
// Convert it to hexadecimal format
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16)
.substring(1));
}
return sb.toString();
}
This is how I have written in Go:
func HashSha512(original string) (string, error) {
salt := "abcde687869"
originalStrBytes := []byte(original)
sha512Hasher := sha512.New()
saltedValueBytes := append(originalStrBytes, []byte(salt)...)
sha512Hasher.Write(saltedValueBytes)
hashedBytes := sha512Hasher.Sum(nil)
s := ""
var x uint64 = 0x100
y := byte(x)
for i := 0; i < len(hashedBytes); i++ {
s += fmt.Sprintf("%x", ((hashedBytes[i] & 0xff) + y))[1:]
}
return s, nil
}
But the strings generated are not the same.
Go playground link: https://play.golang.com/p/uXaw7y2tklN
String generated is
99461a225184c478b8398c7f0dcc1d3afed107660d08a7282a10f5e2ab6
The string generated for same string in java is
020e93364e5186b7d4ac211cd116425234937d390fcc4e1c554fa1e4bafcb934493047ab841e06f00aa28aabee43b737a6bae2f3fc52e431dde724e691aa952d
What am I doing wrong?
答案1
得分: 2
Go代码对消息+盐进行哈希处理。Java代码对盐+消息进行哈希处理。将Go代码中的顺序调换以匹配Java代码。
在转换为十六进制时,使用整数值而不是字节。当使用字节时,0x100会转换为零:
s += fmt.Sprintf("%x", ((int(hashedBytes[i]) & 0xff) + 0x100))[1:]
更好的做法是使用库函数进行转换。使用encoding/hex:
return hex.EncodeToString(hashedBytes)
使用fmt:
return fmt.Sprintf("%x", hashedBytes)
字符串转换为字节时可能存在差异。Java代码使用平台的默认字符集。假设Go应用程序使用UTF-8编码字符串,这是典型的情况,转换后的字节是UTF-8编码的。
以下是函数的简化版本:
func HashSha512hex(original string) (string, error) {
salt := "abcde6786"
h := sha512.New()
io.WriteString(h, salt)
io.WriteString(h, original)
s := h.Sum(nil)
return hex.EncodeToString(s), nil
}
英文:
The Go code hashes message + salt. The Java code hashes salt + message. Swap the order in the Go code to match the Java code.
Use integer values instead of bytes in the conversion to hex. The 0x100 is converted to zero when using bytes:
s += fmt.Sprintf("%x", ((int(hashedBytes[i]) & 0xff) + 0x100))[1:]
Better yet, use a library function for the conversion. Using encoding/hex:
return hex.EncodeToString(hashedBytes)
Using fmt:
return fmt.Sprintf("%x", hashedBytes)
There may be a difference in how the strings are encoded to bytes. The Java code uses the platform's default charset. Assuming that the Go application uses UTF-8 encode strings as is typical, the converted bytes are UTF-8 encoded.
Here's a simpler version of the function:
func HashSha512hex(original string) (string, error) {
salt := "abcde6786"
h := sha512.New()
io.WriteString(h, salt)
io.WriteString(h, original)
s := h.Sum(nil)
return hex.EncodeToString(s), nil
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论