将[32]byte转换为[8]uint32

3

我有256位存储在[32]byte中。

我想将其转换为[8]uint32,其中第一个uint32存储前四个字节,以此类推。

我即将编写一个函数来通过将位移动到正确的位置等方式完成此操作,不知道在Go语言中是否有更简单的方法?


可能是这个问题的重复:在golang中将[]uint32转换为[]byte,反之亦然 - WiredPrairie
2个回答

10

使用binary.ByteOrder

encoding/binary包使得读取字节切片中uint32值变得非常容易。binary.ByteOrder接口类型的值可用于此操作。该包还导出了一个binary.LittleEndian变量,您可以直接使用它。将其放入简单的for循环中以读取所有8个值:

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)

输出(在Go Playground 上尝试):

[1 2 0 0 0 0 0 0]

当然,这对任何字节数(是4的倍数)都适用,而不仅仅是32。
使用binary.Read() 另一个更简短的选择是使用binary.Read()
func Read(r io.Reader, order ByteOrder, data interface{}) error

当然,这需要一个io.Reader,你可以使用bytes.NewBuffer()。这样转换只需一行代码:
data := [32]byte{1, 0, 0, 0, 2}
ints := [8]uint32{}

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

fmt.Println(ints, err)

输出(在Go Playground上尝试):
[1 2 0 0 0 0 0 0] <nil>

使用 unsafe.Pointer

为了完整起见,这里还有另一种不安全的方法。由于数组在内存中按顺序排列,因此两个数组占用相同的大小。我们可以将输入的内存区域解释为输出类型的值:

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

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

fmt.Println(ints)

输出(在Go Playground上尝试):

[1 2 0 0 0 0 0 0]

这是解决任务效率最高但也最不安全的方法。 在这种情况下,按照所示的方式操作是安全的,但请谨慎使用unsafe包,只当无他选择时再使用。许多看似相似的情况可能无法正常工作。我们“幸运”的是,我们拥有数组输入以小端字节顺序给出,但对于切片和/或不同的字节顺序,情况就会有所不同。上述提供的另外两种方法更加通用,并且适用于切片和数组。

1
由于元素数量是恒定的,OP的展开解决方案可能会更快。 - user142162
@TimCooper也许是这样,但他正在寻找一种更_简单_的方法,而不是更_快_的方法。 - icza

1

使用以下类似的东西似乎可以做到:

data_uint32[0] = binary.LittleEndian.Uint32(data_bytes[0:4])
data_uint32[1] = binary.LittleEndian.Uint32(data_bytes[4:8])
data_uint32[2] = binary.LittleEndian.Uint32(data_bytes[8:12])
data_uint32[3] = binary.LittleEndian.Uint32(data_bytes[12:16])
data_uint32[4] = binary.LittleEndian.Uint32(data_bytes[16:20])
data_uint32[5] = binary.LittleEndian.Uint32(data_bytes[20:24])
data_uint32[6] = binary.LittleEndian.Uint32(data_bytes[24:28])
data_uint32[7] = binary.LittleEndian.Uint32(data_bytes[28:32])

也许还有更简单的方法,但现在这个方法就够了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接