Convert [32]byte to [8]uint32

user3340499 :

I have 256 bits stored in a [32]byte.

I want to convert this to an [8]uint32, with the first uint32 storing the first four bytes, etc.

I'm about to write a function that does this by shifting the bits into the correct positions etc, I wonder if there is an easier way to do this in Go?

icza :

Using binary.ByteOrder

The encoding/binary package makes it easy, values of the binary.ByteOrder interface type can be used to read uint32 values from byte slices. There is a binary.LittleEndian exported variable which you can use out of the box. Put this in a simple for loop to read all 8 values:

data := [32]byte{1, 0, 0, 0, 2}
ints := [8]uint32{}

for i := 0; i < len(data); i += 4 {
    ints[i/4] = binary.LittleEndian.Uint32(data[i:])
}

fmt.Println(ints)

Output (try it on the Go Playground):

[1 2 0 0 0 0 0 0]

And this of course works for any number of bytes (being multiple of 4), not just for 32.

Using binary.Read()

Another, even shorter alternative would be to use binary.Read():

func Read(r io.Reader, order ByteOrder, data interface{}) error

This of course requires an io.Reader, for which you may use bytes.NewBuffer(). This way the conversion is a simple line:

data := [32]byte{1, 0, 0, 0, 2}
ints := [8]uint32{}

err := binary.Read(bytes.NewBuffer(data[:]), binary.LittleEndian, &ints)

fmt.Println(ints, err)

Output (try it on the Go Playground):

[1 2 0 0 0 0 0 0] <nil>

Using unsafe.Pointer

For completeness, here's yet another, unsafe way. Since arrays are laid out sequentially in memory, both arrays occupy the same size. We can interpret the memory area of the input as a value of the output type:

data := [32]byte{1, 0, 0, 0, 2}
ints := [8]uint32{}

ints = *(*[8]uint32)((unsafe.Pointer)(&data))

fmt.Println(ints)

Output (try it on the Go Playground):

[1 2 0 0 0 0 0 0]

This is the most efficient and the most unsafe way to solve your task.

In this case it's safe to do it like presented, but use package unsafe with caution and as a last resort. Many other, seemingly very similar cases might not work. We were "lucky" since we had arrays and input was given in little endian byte order, but with slices and / or with different byte order it would be a different story. The above presented 2 other ways are more general and work both with slices and arrays.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related