user200783
user200783

Reputation: 14346

Append the bytes of a uint32 to a byte slice?

If I have an existing []byte, what is the recommended way to append the bytes of one or more uint32 value(s) to it?

For example, what should I replace // ??? with:

s := []byte{0x00, 0x01, 0x02, 0x03}

u := uint32(0x07060504)
// ???

fmt.Println(s)  // Should print [0 1 2 3 4 5 6 7]

Edit: One option would be s = append(s, byte(u)); s = append(s, byte(u >> 8)); s = append(s, byte(u >> 16)); s = append(s, byte(u >> 24)), but is there a more idiomatic way to do this? Perhaps using package binary and/or package bytes?

Upvotes: 0

Views: 1238

Answers (3)

Laevus Dexter
Laevus Dexter

Reputation: 502

There's unsafe (actually safe, if you will only copy its bytes) way to get byte representation of any primitive:

const sizeUInt32 = int(unsafe.Sizeof(uint32(0)))

func GetBytesUInt32(i *uint32) []byte {
   return (*[1 << 30]byte)(unsafe.Pointer(i))[:sizeUInt32:sizeUInt32]
}

https://play.golang.org/p/WPC5jeYLDth

Created slice will carry passed int's storage, so by making a manipulations with it keep in mind that uint32 value will be changed too.


Hey, what a hate without discussion? I realize that you guys don't like unsafe code, and I realize that such answer isn't recommended way for which topic starter looking... but I think that such place as stackoverflow should offer all of possibles ways to implement thing people googling for.

Upvotes: -3

Burak Serdar
Burak Serdar

Reputation: 51657

encoding/binary has the functions you need:

import "encoding/binary"

b := make([]byte,4)
binary.LittleEndian.PutUint32(b, u)
s = append(s, b)

Upvotes: 1

Thundercat
Thundercat

Reputation: 121209

One option is to append the individual bytes as suggested in the question. The multiple append calls can be combined into a single call:

s = append(s, byte(u), byte(u>>8), byte(u>>16), byte(u>>24))

The binary package can also be used as the question suggests:

var b [4]byte
binary.LittleEndian.PutUint32(b[:], u)
s = append(s, b[:]...)

Run it on the Go playground.

The last snippet should allocate b on the stack. If it does not, then the extra heap allocation can be avoided with the following code:

s = append(s, "    "...) // append four bytes (the values don't matter)
binary.LittleEndian.PutUint32(s[len(s)-4:], u) // overwrite those bytes with the uint32

Upvotes: 3

Related Questions