如果我使用语言" 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版本一样工作?
答案 0 :(得分:17)
为什么他们不同?
他们不是,真的。它们是相同的位。只是Java没有无符号字节 - 因此任何顶部位设置的字节都是负数。在每种情况下,你都会看到Java结果= Go结果 - 256。
如果将两个字节数组转换为十六进制或base64,您将看到相同的结果。
答案 1 :(得分:4)
Here is the Go code会产生相同的结果:
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 doc确实提到了:
没有'
u
'旗。如果整数具有无符号类型,则它们将无符号打印。
由于Numeric Types定义:
byte
uint8
别名
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=