dousi7579 2012-12-01 07:02
浏览 685
已采纳

将[8] byte转换为uint64

all. I'm encountering what seems to be a very strange problem. (It could be that it's far past when I should be asleep, and I'm overlooking something obvious.)

I have a []byte with length 8 as a result of some hex decoding. I need to produce a uint64 in order to use it. I have tried using binary.Uvarint(), from encoding/binary to do so, but it seems to only use the first byte in the array. Consider the following example.

package main

import (
    "encoding/binary"
    "fmt"
)

func main() {
    array := []byte{0x00, 0x01, 0x08, 0x00, 0x08, 0x01, 0xab, 0x01}
    num, _ := binary.Uvarint(array[0:8])
    fmt.Printf("%v, %x
", array, num)
}

Here it is on play.golang.org.

When that is run, it displays the num as 0, even though, in hex, it should be 000108000801ab01. Furthermore, if one catches the second value from binary.Uvarint(), it is the number of bytes read from the buffer, which, to my knowledge, should be 8, even though it is actually 1.

Am I interpreting this wrong? If so, what should I be using instead?

Thanks, you all. :)

  • 写回答

3条回答 默认 最新

  • dongshijiao6890 2012-12-01 08:45
    关注

    You're decoding using a function whose use isn't the one you need :

    Varints are a method of encoding integers using one or more bytes; numbers with smaller absolute value take a smaller number of bytes. For a specification, see http://code.google.com/apis/protocolbuffers/docs/encoding.html.

    It's not the standard encoding but a very specific, variable byte number, encoding. That's why it stops at the first byte whose value is less than 0x080.

    As pointed by Stephen, binary.BigEndian and binary.LittleEndian provide useful functions to decode directly :

    type ByteOrder interface {
        Uint16([]byte) uint16
        Uint32([]byte) uint32
        Uint64([]byte) uint64
        PutUint16([]byte, uint16)
        PutUint32([]byte, uint32)
        PutUint64([]byte, uint64)
        String() string
    }
    

    So you may use

    package main
    
    import (
        "encoding/binary"
        "fmt"
    )
    
    func main() {
        array := []byte{0x00, 0x01, 0x08, 0x00, 0x08, 0x01, 0xab, 0x01}
        num := binary.LittleEndian.Uint64(array)
        fmt.Printf("%v, %x", array, num)
    }
    

    or (if you want to check errors instead of panicking, thanks jimt for pointing this problem with the direct solution) :

    package main
    
    import (
        "encoding/binary"
        "bytes"
        "fmt"
    )
    
    func main() {
        array := []byte{0x00, 0x01, 0x08, 0x00, 0x08, 0x01, 0xab, 0x01}
        var num uint64
        err := binary.Read(bytes.NewBuffer(array[:]), binary.LittleEndian, &num)
        fmt.Printf("%v, %x", array, num)
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥50 如何增强飞上天的树莓派的热点信号强度,以使得笔记本可以在地面实现远程桌面连接
  • ¥15 MCNP里如何定义多个源?
  • ¥20 双层网络上信息-疾病传播
  • ¥50 paddlepaddle pinn
  • ¥20 idea运行测试代码报错问题
  • ¥15 网络监控:网络故障告警通知
  • ¥15 django项目运行报编码错误
  • ¥15 请问这个是什么意思?
  • ¥15 STM32驱动继电器
  • ¥15 Windows server update services