Go SHA-256哈希值与Java SHA-256哈希值不同。

5
如果我在“GO”语言中生成SHA-256哈希值,与Java版本相比,得到的字节数组不同。
这是GO版本:
fmt.Println(getSha256([]byte("5nonce=5")))

生成的数组看起来像这样:
41 79 186 235 199 123 95 226 16 59 51 161 112 245 192 50 21 66 180 250 179 109 153 18 233 148 16 237 156 69 163 150]

这个Java代码应该能够完成相同的功能:
MessageDigest md = MessageDigest.getInstance("SHA-256");

md.update("5nonce=5".getBytes()); 
byte[] digest = md.digest();

但是结果会以字节数组的形式呈现

[41, 79, -70, -21, -57, 123, 95, -30, 16, 59, 51, -95, 112, -11, -64, 50, 21, 66, -76, -6, -77, 109, -103, 18, -23, -108, 16, -19, -100, 69, -93, -106]

它们为什么不同?我需要如何更改Java版本,使其与Go版本完全相同?

2个回答

16
为什么它们不同?
其实它们并没有区别,它们是相同的比特位。只是 Java 没有无符号字节 - 所以任何具有设置了最高位的字节都是负数。在每种这样的情况下,您会看到 Java 结果 = Go 结果 - 256。
如果您将两个字节数组转换为十六进制或 base64,则会看到相同的结果。

谢谢,将它们转换为base64使得比较变得更容易了,而且它们确实是相同的。 - jan

4

这里是Go语言代码,可以生成相同的结果:

package main

import "fmt"
import "crypto/sha256"

func main() {
    sum224 := sha256.Sum256([]byte("5nonce=5"))
    s := make([]int8, sha256.Size)
    for i := range sum224 {
        s[i] = int8(sum224[i])
    }
    fmt.Printf("%d", s)
}

[41 79 -70 -21 -57 123 95 -30 16 59 51 -95 112 -11 -64 50 21 66 -76 -6 -77 109 -103 18 -23 -108 16 -19 -100 69 -93 -106]

fmt文档 中提到:

没有 'u' 标志。如果整数类型是无符号的,则打印为无符号。

由于数字类型定义如下:

  • byteuint8 的别名
  • uint8 是所有 8 位无符号整数的集合(从 0 到 255)
  • int8 是所有 8 位有符号整数的集合(从 -128 到 127)

这就是为什么需要将 byte(无符号)转换为带符号的 int8 才能看到相同的结果。


如果添加 Base64 编码(参见Golang Playground),则可以获得更容易比较的结果:

import "encoding/base64"

res := base64.StdEncoding.EncodeToString([]byte(sum224[:]))
fmt.Println(res)

那将返回:

KU+668d7X+IQOzOhcPXAMhVCtPqzbZkS6ZQQ7ZxFo5Y=

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接