当前位置: > > > > Go中String的MD5摘要与Java中的不同
Go中String的MD5摘要与Java中的不同
来源:stackoverflow
2024-04-24 12:18:49
0浏览
收藏
大家好,我们又见面了啊~本文《Go中String的MD5摘要与Java中的不同》的内容中将会涉及到等等。如果你正在学习Golang相关知识,欢迎关注我,以后会给大家带来更多Golang相关文章,希望我们能一起进步!下面就开始本文的正式内容~
问题内容
我正在 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];
}
在 go 中:
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 自然存储字符串的方式(因此您得到 utf-当您执行 []byte("some text")) 时为 8 字节序列。
这将导致仅使用 ascii 表字符(其代码小于 128)的文本获得相同的输入数据,但对于包含高于该字符的文本将导致不同的数据(因为它们将转换为多字符) utf-8 中的字节序列)。需要记住的事情!
简化
另请注意,要计算某些数据的 md5 摘要,您可以简单地使用 函数,因为无论如何您都会丢弃创建的 :
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 中的 byte 是 uint8 的别名,范围是 0..255。因此,如果要比较结果,则必须将 java 负值移动 256(加上 256)。
如果将字节数组(或切片)转换为十六进制表示形式,它将是相同的(十六进制表示形式没有“符号”属性)。
您可以在这里阅读更多相关信息:
文中关于的知识介绍,希望对你的学习有所帮助!若是受益匪浅,那就动动鼠标收藏这篇《Go中String的MD5摘要与Java中的不同》文章吧,也可关注米云公众号了解相关技术文章。
