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?
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.
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>
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.
Comments