Golang – 打包和哈希二进制数据

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

Golang - Packing and hashing binary data

问题

我正在尝试学习Golang,并且有Python的背景。我目前正在努力理解如何将变量打包成二进制格式(带有校验和)。在Python中,我会使用类似以下的代码:

  1. import struct
  2. import hashlib
  3. a = 100
  4. b = "foo\x00\x00" # 填充到固定长度
  5. packet = struct.pack('<B5s', a, b)
  6. digest = hashlib.sha256(packet).digest()
  7. packet += digest

为了在Go中实现相同的功能,我尝试了以下代码:

  1. package main
  2. import (
  3. "crypto/sha256"
  4. "fmt"
  5. "encoding/binary"
  6. "bytes"
  7. )
  8. type packet struct {
  9. a uint8
  10. b string
  11. }
  12. func main() {
  13. var p = packet{}
  14. p.a = 1
  15. p.b = "foo\x00\x00"
  16. buf := new(bytes.Buffer)
  17. binary.Write(buf, binary.LittleEndian, &p)
  18. h := sha256.New()
  19. h.Write(buf.Bytes())
  20. fmt.Printf("% x\n", p)
  21. }

然而,不幸的是,无论我如何尝试,似乎都陷入了变量类型冲突的噩梦(缓冲区、字节数组和字符串)。我希望能得到一些指导,看看我是否采取了正确的方法。

英文:

I'm attempting to learn Golang and have a background in Python. I'm currently trying to get my head around how to pack variables into a binary format (with a checksum). In Python I'd use something like:

  1. import struct
  2. import hashlib
  3. a = 100
  4. b = &quot;foo\x00\x00&quot; # Padded to fixed length
  5. packet = struct.pack(&#39;&lt;B5s&#39;, a, b)
  6. digest = hashlib.sha256(packet).digest()
  7. packet += digest

To do the same thing in Go, I'm trying code like this:

  1. package main
  2. import (
  3. &quot;crypto/sha256&quot;
  4. &quot;fmt&quot;
  5. &quot;encoding/binary&quot;
  6. &quot;bytes&quot;
  7. )
  8. type packet struct {
  9. a uint8
  10. b string
  11. }
  12. func main() {
  13. var p = packet{}
  14. p.a = 1
  15. p.b = &quot;foo\x00\x00&quot;
  16. buf := new(bytes.Buffer)
  17. binary.Write(buf, binary.LittleEndian, &amp;p)
  18. h := sha256.New()
  19. h.Write(buf.String())
  20. fmt.Printf(&quot;% x\n&quot;, p)
  21. }

Unfortunately, however I attack it I seem to get into a nightmare of clashing variable types (buffers, byte arrays and strings). I'd appreciate some guidance as to whether I'm taking even remotely the right approach.

答案1

得分: 5

更新为可工作的代码。

  1. package main
  2. import (
  3. "bytes"
  4. "crypto/sha256"
  5. "encoding/binary"
  6. "fmt"
  7. )
  8. type packet struct {
  9. a uint8
  10. b []byte
  11. }
  12. func main() {
  13. var p = packet{}
  14. p.a = 1
  15. p.b = []byte("foo\x00\x00")
  16. buf := bytes.Buffer{}
  17. err := binary.Write(&buf, binary.BigEndian, p.a)
  18. if err != nil {
  19. fmt.Println(err)
  20. }
  21. _, err = buf.Write(p.b)
  22. if err != nil {
  23. fmt.Println(err)
  24. }
  25. h := sha256.New()
  26. h.Write(buf.Bytes())
  27. hash := h.Sum([]byte{})
  28. fmt.Printf("% x\n", hash)
  29. }

你是对的,使用encoding/binary在结构体中写入可能具有动态长度的项(切片和字符串)确实有些麻烦。你可能会对查看"encoding/gob"包感兴趣,它可以自动编码字符串(尽管它与你这里的填充字符串不兼容)。

英文:

Updated to something that works.

  1. package main
  2. import (
  3. &quot;bytes&quot;
  4. &quot;crypto/sha256&quot;
  5. &quot;encoding/binary&quot;
  6. &quot;fmt&quot;
  7. )
  8. type packet struct {
  9. a uint8
  10. b []byte
  11. }
  12. func main() {
  13. var p = packet{}
  14. p.a = 1
  15. p.b = []byte(&quot;foo\x00\x00&quot;)
  16. buf := bytes.Buffer{}
  17. err := binary.Write(&amp;buf, binary.BigEndian, p.a)
  18. if err != nil {
  19. fmt.Println(err)
  20. }
  21. _, err = buf.Write(p.b)
  22. if err != nil {
  23. fmt.Println(err)
  24. }
  25. h := sha256.New()
  26. h.Write(buf.Bytes())
  27. hash := h.Sum([]byte{})
  28. fmt.Printf(&quot;% x\n&quot;, hash)
  29. }

http://play.golang.org/p/t8ltu_WCpe

You're right that it's a bit painful to write structs with possibly dynamic length items in them (slices and strings) using encoding/binary. You might be interested in checking out the "encoding/gob" package that encodes strings automatically (although it isn't compatible with the padded string you've got here).

huangapple
  • 本文由 发表于 2014年1月4日 23:07:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/20922598.html
匿名

发表评论

匿名网友

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

确定