http://play.golang.org/p/RqScJVvpS7
package main
import (
"fmt"
"math/rand"
"encoding/binary"
)
func main() {
buffer := []byte{0, 0, 0, 0, 0, 0, 0, 0}
num := rand.Int63()
count := binary.PutVarint(buffer, num)
fmt.Println(count)
}
Run Code Online (Sandbox Code Playgroud)
我之前有这个工作,num当时只是一个递增uint64而我正在使用binary.PutUvarint但现在它是一个随机的int64并且binary.PutVarint我收到一个错误:
panic: runtime error: index out of range
goroutine 1 [running]:
encoding/binary.PutUvarint(0x1042bf58, 0x8, 0x8, 0x6ccb, 0xff9faa4, 0x9acb0442, 0x7fcfd52, 0x4d658221)
/usr/local/go/src/encoding/binary/varint.go:44 +0xc0
encoding/binary.PutVarint(0x1042bf58, 0x8, 0x8, 0x6ccb, 0x7fcfd52, 0x4d658221, 0x14f9e0, 0x104000e0)
/usr/local/go/src/encoding/binary/varint.go:83 +0x60
main.main()
/tmp/sandbox010341234/main.go:12 +0x100
Run Code Online (Sandbox Code Playgroud)
我错过了什么?我本以为这是一个微不足道的变化......
编辑:我只是尝试扩展我的缓冲区数组.对于一些奇怪的原因,它的工作原理和我获得count的10.怎么可能?int64是64位= 8字节,对吗?
引用以下文件encoding/binary:
varint函数使用可变长度编码对单个整数值进行编码和解码; 较小的值需要较少的字节.有关规范,请参阅https://developers.google.com/protocol-buffers/docs/encoding.
所以binary.PutVarint()它不是固定的,而是可变长度的编码.传递时int64,对于大数字,它将需要超过8个字节,对于小数字,它将需要少于8个字节.由于您编码的数字是随机数,因此即使在其最高字节中也会有随机位.
看这个简单的例子:
buffer := make([]byte, 100)
for num := int64(1); num < 1<<60; num <<= 4 {
count := binary.PutVarint(buffer, num)
fmt.Printf("Num=%d, bytes=%d\n", num, count)
}
Run Code Online (Sandbox Code Playgroud)
输出:
Num=1, bytes=1
Num=16, bytes=1
Num=256, bytes=2
Num=4096, bytes=2
Num=65536, bytes=3
Num=1048576, bytes=4
Num=16777216, bytes=4
Num=268435456, bytes=5
Num=4294967296, bytes=5
Num=68719476736, bytes=6
Num=1099511627776, bytes=6
Num=17592186044416, bytes=7
Num=281474976710656, bytes=8
Num=4503599627370496, bytes=8
Num=72057594037927936, bytes=9
Run Code Online (Sandbox Code Playgroud)
可变长度编码的本质是小数字使用较少的字节,但只有当大数字可能使用超过8个字节(即大小int64)时才能实现.
特定编码的详细信息位于链接页面上.
一个非常简单的例子是:一个字节是8位.使用7位输出字节作为"有用"位来编码数据/数字.如果最高位为1,则表示需要更多字节.如果最高位为0,我们就完成了.您可以看到可以使用1个输出字节(例如n=10)编码小数字,而我们为每个7位有用数据使用1个额外位,因此如果输入数字使用所有64位,我们最终会得到更多超过8个字节:需要10个组来覆盖64位,因此我们需要10个字节(9个组只有9*7 = 63位).