登录
首页 >  Golang >  Go问答

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

来源:stackoverflow

时间:2024-04-24 12:18:49 204浏览 收藏

大家好,我们又见面了啊~本文《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 摘要,您可以简单地使用 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)。

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

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

文中关于的知识介绍,希望对你的学习有所帮助!若是受益匪浅,那就动动鼠标收藏这篇《Go中String的MD5摘要与Java中的不同》文章吧,也可关注golang学习网公众号了解相关技术文章。

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>