我遇到了一个似乎很奇怪的问题。(可能是我早就应该睡觉了,我忽略了一些明显的东西。)
我有一个长度为8的[]byte
作为一些十六进制解码的结果。为了使用它,我需要产生一个uint64
。我已经尝试使用binary.Uvarint()
,从encoding/binary
这样做,但它似乎只使用数组中的第一个字节。考虑下面的例子。
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\n", array, num)
}
字符串
Here it is on play.golang.org.
当它运行时,它将num
显示为0
,即使在十六进制中,它应该是000108000801ab01
。此外,如果从binary.Uvarint()
中捕获第二个值,则它是从缓冲区读取的字节数,据我所知,应该是8,即使它实际上是1。
我理解错了吗?如果是的话,我应该用什么来代替?
谢谢大家:)
3条答案
按热度按时间qc6wkl3g1#
你正在使用一个函数进行解码,而这个函数的用途不是你需要的:
变量类型是一种使用一个或多个字节对整数进行编码的方法;具有较小绝对值的数字占用较少的字节数。有关规范,请参见http://code.google.com/apis/protocolbuffers/docs/encoding.html。
这不是标准编码,而是一种非常特殊的可变字节数编码,这就是为什么它在第一个值小于0x 080的字节处停止。
正如Stephen所指出的,binary.BigEndian和binary.LittleEndian提供了有用的函数来直接解码:
字符串
所以你可以用
型
或者(如果你想检查错误而不是恐慌,感谢jimt用直接解决方案指出这个问题):
型
oipij1gg2#
如果不关心字节顺序,你可以试试这个:
字符串
http://play.golang.org/p/aM2r40ANQC
xdnvmnnf3#
如果你看一下Uvarint的函数,你会发现它并不像你期望的那样是一个直接的转换。
老实说,我还没有弄清楚它需要什么样的字节格式(参见编辑)。
但是写你自己的几乎是微不足道的:
字符串
编辑
字节格式是我不熟悉的。它是一种可变宽度编码,每个字节的最高位是一个标志。
如果设置为0,则该字节是序列中的最后一个。
如果设置为1,则编码应继续下一个字节。
只有每个字节的低7位用于构建uint 64值。第一个字节将设置uint 64的低7位,随后的字节位8-15等。