英文:
Go SHA-256 hash differs from Java SHA-256 hash
问题
如果我在"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版本完全相同?
英文:
If I generate the SHA-256 hash in the language "GO", I get a different byte-Array compared to the Java equivalent.
This is the GO version:
fmt.Println(getSha256([]byte("5nonce=5")))
The resulting array looks like:
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]
This one should do the same in Java code:
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update("5nonce=5".getBytes());
byte[] digest = md.digest();
But results in this byte array
[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]
Why are they different? How do I need to change the java version to work exactly like the Go version?
答案1
得分: 16
为什么它们不同?
实际上它们并不不同,它们是相同的位。只是Java没有无符号字节 - 所以任何最高位设置的字节都是负数。在每种这样的情况下,你会看到Java的结果 = Go的结果 - 256。
如果你将两个字节数组转换为十六进制或base64,你会看到相同的结果。
英文:
> Why are they different?
They're not, really. They're the same bits. It's just that Java doesn't have unsigned bytes - so any byte with the top bit set is negative. In every case like that, you'll see that Java result = Go result - 256.
If you convert both byte arrays to hex or base64, you'll see same results.
答案2
得分: 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)
}
fmt
文档中提到:
没有'u'标志。如果整数具有无符号类型,则打印为无符号。
由于数值类型定义了:
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=
英文:
Here is the Go code which would produce the same result:
<!-- language-all: 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]
The fmt doc does mention:
> There is no 'u
' flag. Integers are printed unsigned if they have unsigned type.
Since Numeric Types defines:
byte
alias foruint8
uint8
the set of all unsigned 8-bit integers (0 to 255)int8
the set of all signed 8-bit integers (-128 to 127)
That is why you would need to convert byte
(unsigned) into signed int8
to see the same.
If you add base64 encoding (see golang playground), you can get a result easier to compare:
import "encoding/base64"
res := base64.StdEncoding.EncodeToString([]byte(sum224[:]))
fmt.Println(res)
That returns:
KU+668d7X+IQOzOhcPXAMhVCtPqzbZkS6ZQQ7ZxFo5Y=
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论