所有.我遇到了一个似乎很奇怪的问题.(可能是我睡着了很久,我忽略了一些显而易见的事情.)
[]byte
由于某些十六进制解码,我的长度为8.我需要生产一个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)
}
Run Code Online (Sandbox Code Playgroud)
当它运行时,它显示num
as 0
,即使它是十六进制,它应该是000108000801ab01
.此外,如果一个人从中获取第二个值binary.Uvarint()
,那么它是从缓冲区读取的字节数,据我所知,它应该是8,即使它实际上是1.
我在解释这个错误吗?如果是这样,我应该使用什么呢?
谢谢,大家好.:)
Den*_*ret 16
您正在使用一个函数进行解码,该函数的使用不是您需要的函数:
Varints是一种使用一个或多个字节编码整数的方法; 绝对值较小的数字占用较少的字节数.有关规范,请参阅 http://code.google.com/apis/protocolbuffers/docs/encoding.html.
它不是标准编码,而是非常具体的可变字节数编码.这就是为什么它在第一个字节停止,其值小于0x080.
正如Stephen所指出的,binary.BigEndian和binary.LittleEndian提供了直接解码的有用功能:
type ByteOrder interface {
Uint16([]byte) uint16
Uint32([]byte) uint32
Uint64([]byte) uint64
PutUint16([]byte, uint16)
PutUint32([]byte, uint32)
PutUint64([]byte, uint64)
String() string
}
Run Code Online (Sandbox Code Playgroud)
所以你可以使用
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)
}
Run Code Online (Sandbox Code Playgroud)
或者(如果你想检查错误而不是恐慌,感谢jimt用直接解决方案指出这个问题):
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)
}
Run Code Online (Sandbox Code Playgroud)