gpt4 book ai didi

java - Go 中 String 的 MD5 摘要与 Java 不同

转载 作者:数据小太阳 更新时间:2023-10-29 03:43:04 25 4
gpt4 key购买 nike

我正在用 Java 创建 MD5 摘要,这是计算输入字符串的 4 字节十六进制散列所必需的。以下是 Java 中的代码:

public static String hashString(String s) {
MessageDigest md;
try {
md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(s.getBytes("US-ASCII"));
byte[] output = new byte[digest.length / 4];
for (int i = 0; i < output.length; i++) {
for (int j = 0; j < digest.length; j += 4) {
System.out.print(digest[j]);
output[i] ^= digest[i + j];
}
}
return getHexString(output);
} catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
return null;
}
}

我想在 Golang 中使用相同的代码,但是,MD5 输出与我在 Java 中得到的不同。下面是 Go 中的代码:

func hashString(s string) string {
md := md5.New()
md.Write([]byte(s))
data := md.Sum(nil)
fmt.Println(data)
output := make([]byte, len(data)/4)
for i := 0; i < len(output); i++ {
for j:=0 ;j < len(data); j++ {
output[i] ^= data[i + j]
fmt.Print(output[i])
}
}
return getHexString(output)
}

我在两个代码示例中都添加了打印语句。由于我是 Go 的新手,我不知道是否有任何其他库或方法可以这样做。我只是按照我在互联网上找到的内容进行操作。如果有人可以提供帮助,那就太好了。

最佳答案

1。不同的循环

您的内部循环不同。

在 Java 中:

for (int j = 0; j < digest.length; j += 4) {
System.out.print(digest[j]);
output[i] ^= digest[i + j];
}

在围棋中:

for j:=0; j < len(data); j++ {
output[i] ^= data[i + j]
fmt.Print(output[i])
}

请注意,在 Java 中您将循环变量递增 4,而在 Go 中仅递增 1。使用:

for j:=0; j < len(data); j += 4 {
output[i] ^= data[i + j]
fmt.Print(output[i])
}

2。返回数据不同

更新:Asker 澄清说这只是发布代码中的错别字,此后已被删除(编辑掉)。

您的 Java 解决方案还返回输出的十六进制表示形式:

return getHexString(output);

但在 Go 中,您返回(完整)MD5 摘要的十六进制表示:

return getHexString(md.Sum(nil))

所以在 Go 中也这样做:

return getHexString(output)

3。输入字符串=>字节序列转换

最后一点。在 Java 中,您使用 US-ASCII 编码将输入字符串转换为字节序列,而在 Go 中,您使用输入字符串的 UTF-8 编码序列,因为这就是 Go 自然地存储字符串的方式(所以当你执行 []byte("some text") 时你会得到 UTF-8 字节序列)。

对于仅使用 ASCII 表字符(其代码小于 128)的文本,这将导致相同的输入数据,但对于包含高于该字符的文本(因为它们将转换为多字符),将导致不同的数据UTF-8 中的字节序列)。有一点要记住!


简化

另请注意,要计算某些数据的 MD5 摘要,您可以简单地使用 md5.Sum()功能,因为您要丢弃创建的 hash.Hash无论如何:

func hashString(s string) string {
dataArr := md5.Sum([]byte(s))
data := dataArr[:]
fmt.Println(data)
output := make([]byte, len(data)/4)
for i := 0; i < len(output); i += 4 {
for j := 0; j < len(data); j++ {
output[i] ^= data[i+j]
fmt.Print(output[i])
}
}
return getHexString(output)
}

字节表示差异

你说结果数组的内容不同。这是因为 Java 中的 byte 类型是有符号的,它的范围是 -128..127,而 Go 中的 byteuint8 的别名,范围是 0..255。所以如果你想比较结果,你必须将负的 Java 值移动 256(加 256)。

如果将字节数组(或 slice )转换为十六进制表示,它将是相同的(十六进制表示没有“符号”属性)。

您可以在这里阅读更多相关信息:Java vs. Golang for HOTP (rfc-4226)

关于java - Go 中 String 的 MD5 摘要与 Java 不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51840459/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com