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:
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
To do the same thing in Go, I'm trying code like this:
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)
}
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.
Updated to something that works.
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
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With