Yod*_*oda -3 java string hash md5 go
我正在用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;
}
}
Run Code Online (Sandbox Code Playgroud)
我想在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)
}
Run Code Online (Sandbox Code Playgroud)
我在两个代码示例中都添加了print语句.由于我是Go的新手,我不知道是否有其他库或方法可以这样做.我只是按照我在网上找到的.如果有人能帮忙解决这个问题真的很棒.
你的内环是不同的.
在Java中:
for (int j = 0; j < digest.length; j += 4) {
System.out.print(digest[j]);
output[i] ^= digest[i + j];
}
Run Code Online (Sandbox Code Playgroud)
在Go:
for j:=0; j < len(data); j++ {
output[i] ^= data[i + j]
fmt.Print(output[i])
}
Run Code Online (Sandbox Code Playgroud)
请注意,在Java中,您将循环变量增加4,并在Go中仅增加1.使用:
for j:=0; j < len(data); j += 4 {
output[i] ^= data[i + j]
fmt.Print(output[i])
}
Run Code Online (Sandbox Code Playgroud)
更新: Asker澄清说这只是发布代码中的一个拼写错误,从那时起被删除(已删除).
您的Java解决方案也会返回输出的十六进制表示:
return getHexString(output);
Run Code Online (Sandbox Code Playgroud)
但在Go中,您返回(完整)MD5摘要的十六进制表示:
return getHexString(md.Sum(nil))
Run Code Online (Sandbox Code Playgroud)
所以在Go中也做:
return getHexString(output)
Run Code Online (Sandbox Code Playgroud)
最后一点.在Java中,您使用US-ASCII编码将输入字符串转换为字节序列,而在Go中,您使用UTF-8输入字符串的编码序列,因为这是Go自然存储字符串的方式(因此,当您执行时,您将获得UTF-8字节序列[]byte("some text")).
这将导致仅使用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)
}
Run Code Online (Sandbox Code Playgroud)
你说结果数组的内容是不同的.这是因为byteJava 中的类型是有符号的,它有一个范围-128..127,而在Go中byte是一个别名,uint8有一个范围0..255.因此,如果要比较结果,则必须将负Java值移动256(添加256).
如果将字节数组(或切片)转换为十六进制表示,则它将是相同的(十六进制表示没有"符号"属性).
你可以在这里阅读更多相关信息:用于HOTP的Java与Golang(rfc-4226)
| 归档时间: |
|
| 查看次数: |
389 次 |
| 最近记录: |