2

In Ruby, I'm using the string.unpack method to decode some data. I'm migrating this code into a Golang app, however I can't find a corresponding method in the standard library?

The ruby code is: str.unpack('>LLLff')

What is the best way to implement this in Go?


Example data:

]\x00\x00@\x00\x8C\xD2\x00\x00\x00\x00\x00\x00\x00\x00h.\x9FAjK\x8FG\xC0T\x87UX\xA1CH\xB7\x80\x82}\xBB\xF9\x8F\xBAcqF{\xE31/Zx\xC0\x04\xFF\b\xA0\xBD\a\x9E\x0F\x14c+\b\xD3\xE8\xE1\xC2\x1C7\xBCmd/j\xC1H\x191~\x91F\b5-\x8A\x9F(\\\xF1\x16/\x0F\xEA\xD9\x94rV\xEC\xBB\xCB\x12qJ\x05\b\x04 {R\xB8\xA4\xA9\xD0)v\x97<\xCA\x92\xB6U\b)\x1D\x1D\xF1\x00\xE4U\x8DB\x16/v\xEC[bLTW\xB2\xFB\x0F\x91\x05\xAA\x9C\xBD\x8E\x1A\xFB\xDFUJ\xB8\xDE\xF5m\xC8Z\xC1\v\\|\r;\xB6\xE6\xA6\x13o\x91\xE1\xBA\x9An\x8B\x01W\xB9\"\x12+\x9B[\xC7\xCD\xC2O+\f^|\xE1G\x86.%m\xB2x\xF1j\e\"\xE41Bu_\x16J\xE4M\x7F\xC5U[\xB9\xD0\xC7\xECu\xE53\xB4)\xD5\x80|\xB7.\xD2\f\xF3\x16\x8B\xE3\x13\x81\x02:5\x88\x0F

Should map to: [1073741917, 13798400, 0, 2.4178516392292583e+24, 5.851859700165677e+25]

2

1 Answer 1

4

Try this:

package main

import (
    "bytes"
    "encoding/binary"
    "log"
)

type UnpackedThing struct {
    First  uint32
    Second uint32
    Third  uint32

    Fourth float32
    Fifth  float32
}

func main() {
    input := bytes.NewBufferString("]\x00\x00@\x00\x8C\xD2\x00\x00\x00\x00\x00\x00\x00\x00h.\x9FAjK\x8FG\xC0T\x87UX\xA1CH\xB7\x80\x82}\xBB\xF9\x8F\xBAcqF{\xE31/Zx\xC0\x04\xFF\b\xA0\xBD\a\x9E\x0F\x14c+\b\xD3\xE8\xE1\xC2\x1C7\xBCmd/j\xC1H\x191~\x91F\b5-\x8A\x9F(\\\xF1\x16/\x0F\xEA\xD9\x94rV\xEC\xBB\xCB\x12qJ\x05\b\x04 {R\xB8\xA4\xA9\xD0)v\x97<\xCA\x92\xB6U\b)\x1D\x1D\xF1\x00\xE4U\x8DB\x16/v\xEC[bLTW\xB2\xFB\x0F\x91\x05\xAA\x9C\xBD\x8E\x1A\xFB\xDFUJ\xB8\xDE\xF5m\xC8Z\xC1\v\\|\r;\xB6\xE6\xA6\x13o\x91\xE1\xBA\x9An\x8B\x01W\xB9\"\x12+\x9B[\xC7\xCD\xC2O+\f^|\xE1G\x86.%m\xB2x\xF1j\x1B\"\xE41Bu_\x16J\xE4M\x7F\xC5U[\xB9\xD0\xC7\xECu\xE53\xB4)\xD5\x80|\xB7.\xD2\f\xF3\x16\x8B\xE3\x13\x81\x02:5\x88\x0F")
    var unpacked UnpackedThing

    err := binary.Read(input, binary.LittleEndian, &unpacked)
    if err != nil {
        log.Fatal(err)
    }

    log.Printf("[%d, %d, %d, %f, %f]\n",
        unpacked.First, unpacked.Second, unpacked.Third, unpacked.Fourth, unpacked.Fifth)
}

We're creating a struct that properly represents the binary format, then using binary.Read() to read our bytes into this struct. One thing to note is that golang's strings don't understand \e, so it must be converted to \x1b.

Output:

*@x~/go/src/stackoverflow.com/binunpack⦕ go run main.go
2018/10/07 17:39:16 [1073741917, 13798400, 0, 2417851639229258349412352.000000, 58518597001656773736660992.000000]
*@x~/go/src/stackoverflow.com/binunpack⦕
Sign up to request clarification or add additional context in comments.

2 Comments

Huh, that's cool. I've used encoding/binary before, but somehow up until now I never noticed that it handled structs :)
Yeah, I just came across it the other day myself :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.