尝试在Golang中将字节切片解析为基数为16的数字

时间:2017-10-30 13:09:24

标签: string go

我尝试使用以下值020000解析一段字节作为基数为16的数字,但还没有让它工作。我做错了什么?

package main

import (
    "fmt"
    "strconv"
)

func main() {
    input := []byte{0, 2, 0, 0, 0, 0}
    expectation := 131072

    actual := headerVersion(input)

    if actual != expectation {
        panic(fmt.Sprintf("Expected %v but got %v.", expectation, actual))
    }
}

func headerVersion(input []byte) int {
    output, _ := strconv.ParseUint(string(input), 16, 64)
    return int(output)
}

https://play.golang.org/p/eM5RQAJdoL

2 个答案:

答案 0 :(得分:2)

永远不要忽略错误,请务必检查错误!

func headerVersion(input []byte) int {
    output, err := strconv.ParseUint(string(input), 16, 64)
    if err != nil {
        fmt.Println(err)
    }
    return int(output)
}

向其提供[]byte{0, 2, 0, 0, 0, 0},它将打印:

strconv.ParseUint: parsing "\x00\x02\x00\x00\x00\x00": invalid syntax

执行string(input)时,它会将input的字节转换为文本的UTF-8编码字节。

但是input包含数字的数字值,而不是UTF-8表示! 0数字的数值为'0',等于48

所以你必须将字节值移动'0'(这个演示仅在字节值小于10时有效!):

func headerVersion(input []byte) int {
    for i := range input {
        input[i] += '0'
    }
    output, err := strconv.ParseUint(string(input), 16, 64)
    if err != nil {
        fmt.Println(err)
    }

    return int(output)
}

您的原始headerVersion()函数只有在您输入以下输入时才会给出正确有效的结果:

input := []byte{'0', '2', '0', '0', '0', '0'}

答案 1 :(得分:2)

你有一个原始的字节片,它是构成你想要的数字的字节,但是你要解析它,好像它是组成字节的字符串表示的字节一样。你想要的号码。而不是尝试解析为字符串,而是解析它是什么 - 字节。您可以使用binary package执行此操作,根据其文档:

  

实现数字和字节序列之间的简单转换以及varints的编码和解码。

这正是你想要的。您如何使用它将取决于数据的字节顺序和编码,但文档应该让您朝着正确的方向前进。