使用 binary.PutVarint(...) 时索引超出范围

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)

}

前一段时间我有这个工作,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

我错过了什么?我会认为这是一个微不足道的改变......


编辑:我只是尝试扩展我的缓冲区数组。对于一些奇怪的原因,它的工作原理和我获得count的10。怎么可能?int64是 64 位 = 8 字节,对吗?


慕村225694
浏览 269回答 1
1回答

MMMHUHU

引用文档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 {&nbsp; &nbsp; count := binary.PutVarint(buffer, num)&nbsp; &nbsp; fmt.Printf("Num=%d, bytes=%d\n", num, count)}输出:Num=1, bytes=1Num=16, bytes=1Num=256, bytes=2Num=4096, bytes=2Num=65536, bytes=3Num=1048576, bytes=4Num=16777216, bytes=4Num=268435456, bytes=5Num=4294967296, bytes=5Num=68719476736, bytes=6Num=1099511627776, bytes=6Num=17592186044416, bytes=7Num=281474976710656, bytes=8Num=4503599627370496, bytes=8Num=72057594037927936, bytes=9可变长度编码的本质是小数字使用较少的字节,但这只能在大数字可能使用超过 8 个字节的情况下才能实现(即大小为int64)。具体编码的详细信息在链接页面上。一个非常简单的例子是:一个字节是 8 位。使用输出字节的 7 位作为“有用”位来编码数据/数字。如果最高位为 1,则意味着需要更多字节。如果最高位为 0,我们就完成了。你可以看到,小的数字可以使用1个输出字节编码(如n=10),而我们使用1个额外位,每7位有用的数据,因此,如果输入的号码使用所有64位,我们将结束与更多8 字节以上:需要 10 组来覆盖 64 位,因此我们将需要 10 字节(9 组仅 9*7=63 位)。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go