为什么当我说要8个字节时,Golang没有给我8个字节?

huangapple go评论124阅读模式
英文:

Why is Golang not giving me 8 bytes when I said 8?

问题

我以为 x := make([]byte, N) 应该定义一个长度为 N 的字节切片。但是我得到的输出是 0x015f82a975f9752b,换算成二进制是:

0001 0101 1111 1000 0010 1010 1001 0111 0101 1111 1001 0111 0101 0010 1011

而不是 8。我错过了什么?

请看下面的 genSalt() 函数及其输出。

  1. package main
  2. import (
  3. "crypto/rand"
  4. "crypto/sha256"
  5. "fmt"
  6. "golang.org/x/crypto/pbkdf2"
  7. "log"
  8. )
  9. // 生成一个包含 N 个随机字节的盐
  10. func genSalt() []byte {
  11. ret := make([]byte, 8) // N == 8 (..对吗?)
  12. _, err := rand.Read(ret)
  13. if err != nil {
  14. log.Fatal(err)
  15. }
  16. return ret
  17. }
  18. // 使用 sha256 进行 pbkdf2
  19. // 返回 sha256.Size == 32 字节
  20. func hashPassword(cleartext, salt []byte) []byte {
  21. return pbkdf2.Key([]byte(cleartext), salt, 4096, sha256.Size, sha256.New)
  22. }
  23. func main() {
  24. password := "GNUsNotUnixItsWorse"
  25. salt := genSalt()
  26. hashed := hashPassword([]byte(password), salt)
  27. fmt.Printf("sha256: %x\n", hashed)
  28. fmt.Printf("salt: %x\n", salt)
  29. fmt.Println("len(salt)", len(salt),
  30. "\nlen(hashed)", len(hashed))
  31. // 输出结果(示例):
  32. // sha256: b9c314c8fb8d183fb8773b8b2e2b2b991927915adeba44eb51c8fe6f9e13ee09
  33. // salt: 015f82a975f9752b
  34. // len(salt) 8
  35. // len(hashed) 32
  36. }

由于某种原因,这段代码在 Go Playground 上无法运行,请在本地运行。

(如果这个问题很愚蠢,请原谅,我睡眠不足。)

英文:

I thought x := make([]byte, N) was supposed to define a slice of N bytes. I'm getting 0x015f82a975f9752b as the output for that, which in base 2 is:

0001 0101 1111 1000 0010 1010 1001 0111 0101 1111 1001 0111 0101 0010 1011

Not 8. What am I missing?

See the genSalt() function below and its output.

  1. package main
  2. import (
  3. "crypto/rand"
  4. "crypto/sha256"
  5. "fmt"
  6. "golang.org/x/crypto/pbkdf2"
  7. "log"
  8. )
  9. // generate a salt with N random bytes
  10. func genSalt() []byte {
  11. ret := make([]byte, 8) // N == 8 (..right?)
  12. _, err := rand.Read(ret)
  13. if err != nil {
  14. log.Fatal(err)
  15. }
  16. return ret
  17. }
  18. // pbkdf2 with sha256
  19. // returns sha256.Size == 32 bytes
  20. func hashPassword(cleartext, salt []byte) []byte {
  21. return pbkdf2.Key([]byte(cleartext), salt, 4096, sha256.Size, sha256.New)
  22. }
  23. func main() {
  24. password := "GNUsNotUnixItsWorse"
  25. salt := genSalt()
  26. hashed := hashPassword([]byte(password), salt)
  27. fmt.Printf("sha256: %x\n", hashed)
  28. fmt.Printf("salt: %x\n", salt)
  29. fmt.Println("len(salt)", len(salt),
  30. "\nlen(hashed)", len(hashed))
  31. // OUTPUT (sample):
  32. // sha256: b9c314c8fb8d183fb8773b8b2e2b2b991927915adeba44eb51c8fe6f9e13ee09
  33. // salt: 015f82a975f9752b
  34. // len(salt) 8
  35. // len(hashed) 32
  36. }

For some reason, this won't work in Go Playground, so just run it locally.

(Sorry if this is a retarded question; I'm sleep deprived.)

答案1

得分: 7

1字节 = 8位。

你的输出:0x015f82a975f9752b。这正好是8个字节。

1字节可以表示为2个十六进制数字(1个十六进制数字包含4位,所以1字节 = 8位 = 2个十六进制数字)。

当你将其表示为二进制时:

  1. 二进制: 0001 0101 1111 1000 0010 1010 1001 0111 0101 1111 1001 0111 0101 0010 1011
  2. 十六进制: 1 | 5 | f | 8 | 2 | a | 9 | 7 | 5 | f | 9 | 7 | 5 | 2 | b |
  3. 字节索引: 7. | 6. | 5. | 4. | 3. | 2. | 1. | 0. |

这是60位,因为前面的4位是0,没有打印出来。64位 = 8个字节。

英文:

1 byte = 8 bits.

Your output: 0x015f82a975f9752b. That is exactly 8 bytes.

1 byte can be displayed as 2 hex digits (1 hex digit contains 4 bits, so 1 byte = 8 bits = 2 hex digits).

When you present it as binary:

  1. binary: 0001 0101 1111 1000 0010 1010 1001 0111 0101 1111 1001 0111 0101 0010 1011
  2. hex: 1 | 5 | f | 8 | 2 | a | 9 | 7 | 5 | f | 9 | 7 | 5 | 2 | b |
  3. byte idx: 7. | 6. | 5. | 4. | 3. | 2. | 1. | 0. |

That is 60 bits because the first 4 bits are 0 and not printed. 64 bits = 8 bytes.

huangapple
  • 本文由 发表于 2016年2月20日 18:35:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/35522025.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定