go 中的 sha1 与 python 和 openssl 中的不同
sha1 different in go than in python and openssl
我正在尝试在 go 中构建一个 base64 编码的 sha1 哈希,但我得到的结果与其他编程语言的结果非常不同
package main
import (
"crypto/sha1"
"encoding/base64"
"fmt"
)
func main() {
c := sha1.New()
input := []byte("hello")
myBytes := c.Sum(input)
fmt.Println(base64.StdEncoding.EncodeToString(base64.StdPadding))
}
这段 Go 代码打印出 aGVsbG/aOaPuXmtLDTJVv++VYBiQr9gHCQ==
我的 Python 代码如下所示
import hashlib
import base64
print(base64.b64encode(hashlib.sha1('hello').digest()))
并输出qvTGHdzF6KLavt4PO0gs2a6pQ00=
我的 bash 比较命令如下所示
echo -n hello| openssl dgst -sha1 -binary |base64
并输出这个qvTGHdzF6KLavt4PO0gs2a6pQ00=
这让我假设 python 代码一切正常。
但是为什么去打印另一个结果。
我的错误在哪里?
提前致谢
您使用标准库的方式完全错误。不要假设方法/函数的作用,如果它对您来说是新的,请务必阅读文档。
sha1.New()
returns a hash.Hash
。它的Sum()
方法是不是计算哈希值,而是得到当前的哈希结果,不改变底层哈希状态
hash.Hash
实现了io.Writer
,为了计算一些数据的散列,你必须把那个数据写入其中。 Hash.Sum()
如果您已经分配了一个可选切片,则将结果(哈希)写入其中。如果你想让它分配一个新的,就传nil
。
另外base64.StdEncoding.EncodeToString()
需要你要转换成base64的字节数据(byte slice),所以你必须把checksum数据传给它。在您的代码中,您没有告诉 EncodeToString()
要编码什么。
工作示例:
c := sha1.New()
input := []byte("hello")
c.Write(input)
sum := c.Sum(nil)
fmt.Println(base64.StdEncoding.EncodeToString(sum))
输出符合预期(在 Go Playground 上尝试):
qvTGHdzF6KLavt4PO0gs2a6pQ00=
请注意,crypto/sha1
package also has a handy sha1.Sum()
函数一步完成:
input := []byte("hello")
sum := sha1.Sum(input)
fmt.Println(base64.StdEncoding.EncodeToString(sum[:]))
输出相同。在 Go Playground.
上试试
有一个 example 如何正确使用它。你应该这样做:
c := sha1.New()
io.WriteString(c, "hello")
myBytes := c.Sum(nil)
fmt.Println(base64.StdEncoding.EncodeToString(myBytes))
我正在尝试在 go 中构建一个 base64 编码的 sha1 哈希,但我得到的结果与其他编程语言的结果非常不同
package main
import (
"crypto/sha1"
"encoding/base64"
"fmt"
)
func main() {
c := sha1.New()
input := []byte("hello")
myBytes := c.Sum(input)
fmt.Println(base64.StdEncoding.EncodeToString(base64.StdPadding))
}
这段 Go 代码打印出 aGVsbG/aOaPuXmtLDTJVv++VYBiQr9gHCQ==
我的 Python 代码如下所示
import hashlib
import base64
print(base64.b64encode(hashlib.sha1('hello').digest()))
并输出qvTGHdzF6KLavt4PO0gs2a6pQ00=
我的 bash 比较命令如下所示
echo -n hello| openssl dgst -sha1 -binary |base64
并输出这个qvTGHdzF6KLavt4PO0gs2a6pQ00=
这让我假设 python 代码一切正常。 但是为什么去打印另一个结果。 我的错误在哪里?
提前致谢
您使用标准库的方式完全错误。不要假设方法/函数的作用,如果它对您来说是新的,请务必阅读文档。
sha1.New()
returns a hash.Hash
。它的Sum()
方法是不是计算哈希值,而是得到当前的哈希结果,不改变底层哈希状态
hash.Hash
实现了io.Writer
,为了计算一些数据的散列,你必须把那个数据写入其中。 Hash.Sum()
如果您已经分配了一个可选切片,则将结果(哈希)写入其中。如果你想让它分配一个新的,就传nil
。
另外base64.StdEncoding.EncodeToString()
需要你要转换成base64的字节数据(byte slice),所以你必须把checksum数据传给它。在您的代码中,您没有告诉 EncodeToString()
要编码什么。
工作示例:
c := sha1.New()
input := []byte("hello")
c.Write(input)
sum := c.Sum(nil)
fmt.Println(base64.StdEncoding.EncodeToString(sum))
输出符合预期(在 Go Playground 上尝试):
qvTGHdzF6KLavt4PO0gs2a6pQ00=
请注意,crypto/sha1
package also has a handy sha1.Sum()
函数一步完成:
input := []byte("hello")
sum := sha1.Sum(input)
fmt.Println(base64.StdEncoding.EncodeToString(sum[:]))
输出相同。在 Go Playground.
上试试有一个 example 如何正确使用它。你应该这样做:
c := sha1.New()
io.WriteString(c, "hello")
myBytes := c.Sum(nil)
fmt.Println(base64.StdEncoding.EncodeToString(myBytes))