Golang - 打包和散列二进制数据

7

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

import struct
import hashlib

a = 100
b = "foo\x00\x00"  # Padded to fixed length
packet = struct.pack('<B5s', a, b)
digest = hashlib.sha256(packet).digest()
packet += digest

为了在Go中做同样的事情,我正在尝试编写以下代码:

package main

import (
    "crypto/sha256"
    "fmt"
    "encoding/binary"
    "bytes"
)

type packet struct {
    a uint8
    b string
}

func main() {
    var p = packet{}
    p.a = 1
    p.b = "foo\x00\x00"
    buf := new(bytes.Buffer)
    binary.Write(buf, binary.LittleEndian, &p)
    h := sha256.New()
    h.Write(buf.String())
    fmt.Printf("% x\n", p)
}

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

1个回答

5

更新为可用的内容。

package main

import (
   "bytes"
   "crypto/sha256"
   "encoding/binary"
   "fmt"
)

type packet struct {
   a uint8
   b []byte
}

func main() {
   var p = packet{}
   p.a = 1
   p.b = []byte("foo\x00\x00")
   buf := bytes.Buffer{}
   err := binary.Write(&buf, binary.BigEndian, p.a)
   if err != nil {
       fmt.Println(err)
   }
   _, err = buf.Write(p.b)
   if err != nil {
       fmt.Println(err)
   }
   h := sha256.New()
   h.Write(buf.Bytes())
   hash := h.Sum([]byte{})
   fmt.Printf("% x\n", hash)
}

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

你说得对,在使用encoding/binary时,写入包含可能具有动态长度项目的结构体(切片和字符串)会有些麻烦。你可能会对查看“encoding/gob”包感兴趣,它可以自动编码字符串(尽管与您在此处使用的填充字符串不兼容)。


很不幸,在一些测试后,它似乎并不正常工作。看起来,将p输入binary.Write中并不奏效,除非p只包含整数类型字段。 binary.write之后,“buf”为空,并产生了一个完全空的输入的哈希值。 - Steve Crook
哦,对了... binary.Write 不知道如何处理字符串或字节切片。你必须告诉它如何编码。http://play.golang.org/p/JY1haY65B1 - Eve Freeman
我猜你想写入5个字节。 - Eve Freeman
没错,这有点棘手。你基本上需要为你特定的结构编写自己的二进制编码。你可能会对gob编码感兴趣:http://golang.org/pkg/encoding/gob/ - Eve Freeman
感谢您的帮助Wes,我会查看gob的。目前为止,我已将其(以某种方式)工作。http://play.golang.org/p/P3LcK7kuPY - Steve Crook
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接