【问题标题】:Convert [32]byte to [8]uint32将 [32]byte 转换为 [8]uint32
【发布时间】:2017-10-05 09:54:45
【问题描述】:

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

我想将其转换为[8]uint32,第一个uint32 存储前四个字节,等等。

我即将编写一个函数,通过将位移动到正确的位置等来做到这一点,我想知道在 Go 中是否有更简单的方法来做到这一点?

【问题讨论】:

标签: arrays go type-conversion slice


【解决方案1】:

使用binary.ByteOrder

encoding/binary 包使它变得简单,binary.ByteOrder 接口类型的值可用于从字节片读取uint32 值。有一个 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,并作为最后的手段。许多其他看似非常相似的案例可能不起作用。我们很“幸运”,因为我们有数组 输入是以小端字节顺序给出的,但是对于切片和/或不同的字节顺序,情况就不同了。上面介绍的另外两种方法更通用,适用于切片和数组。

【讨论】:

  • 由于元素数量恒定,OP 展开的解决方案可能会更快。
  • @TimCooper 也许,但他正在寻找一种更简单的方法,而不是更快
【解决方案2】:

看来我可以使用类似的方法来做到这一点:

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])

也许还有更简单的方法,但现在就可以了。

【讨论】:

    猜你喜欢
    • 2017-05-31
    • 1970-01-01
    • 2015-10-03
    • 2019-03-07
    • 1970-01-01
    • 2011-06-08
    • 1970-01-01
    • 2014-07-21
    • 1970-01-01
    相关资源
    最近更新 更多