dtfo55908 2017-05-07 09:37
浏览 357
已采纳

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

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?

  • 写回答

2条回答 默认 最新

  • dsft8327 2017-05-07 11:02
    关注

    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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 运筹学排序问题中的在线排序
  • ¥15 关于docker部署flink集成hadoop的yarn,请教个问题 flink启动yarn-session.sh连不上hadoop,这个整了好几天一直不行,求帮忙看一下怎么解决
  • ¥30 求一段fortran代码用IVF编译运行的结果
  • ¥15 深度学习根据CNN网络模型,搭建BP模型并训练MNIST数据集
  • ¥15 lammps拉伸应力应变曲线分析
  • ¥15 C++ 头文件/宏冲突问题解决
  • ¥15 用comsol模拟大气湍流通过底部加热(温度不同)的腔体
  • ¥50 安卓adb backup备份子用户应用数据失败
  • ¥20 有人能用聚类分析帮我分析一下文本内容嘛
  • ¥15 请问Lammps做复合材料拉伸模拟,应力应变曲线问题