亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Go:二進制編碼機制

Go:二進制編碼機制

Go
神不在的星期二 2021-08-10 16:12:00
我正在嘗試制作一個新的二進制編碼包,因為標準的 Go 編碼/二進制包并不完全符合我的要求。我不明白的是為什么編碼/二進制使用x >>= 7inbinary.PutUvarint而不是x >>= 8. 如果我理解正確,這是故意將位移動 7 而不是 8,這導致存儲 uint64 的總大小為 80 位,而不是 64 位,這顯然是所需的位數。為什么?這是什么原因?這一定與它生成可變長度字節片這一事實有關,但為什么 >>7 會對此有所幫助?以下是二進制編碼函數供您參考:func PutUvarint(buf []byte, x uint64) int {    i := 0    for x >= 0x80 {        buf[i] = byte(x) | 0x80        x >>= 7        i++    }    buf[i] = byte(x)    return i + 1}
查看完整描述

2 回答

?
繁星點點滴滴

TA貢獻1803條經驗 獲得超3個贊

編碼/二進制/ varint.go


package binary


// This file implements "varint" encoding of 64-bit integers.

// The encoding is:

// - unsigned integers are serialized 7 bits at a time, starting with the

//   least significant bits

// - the most significant bit (msb) in each output byte indicates if there

//   is a continuation byte (msb = 1)

// - signed integers are mapped to unsigned integers using "zig-zag"

//   encoding: Positive values x are written as 2*x + 0, negative values

//   are written as 2*(^x) + 1; that is, negative numbers are complemented

//   and whether to complement is encoded in bit 0.

//

// Design note:

// At most 10 bytes are needed for 64-bit values. The encoding could

// be more dense: a full 64-bit value needs an extra byte just to hold bit 63.

// Instead, the msb of the previous byte could be used to hold bit 63 since we

// know there can't be more than 64 bits. This is a trivial improvement and

// would reduce the maximum encoding length to 9 bytes. However, it breaks the

// invariant that the msb is always the "continuation bit" and thus makes the

// format incompatible with a varint encoding for larger numbers (say 128-bit).

一種用于無損數據壓縮的經典技術是霍夫曼編碼,其中較常見的符號通常比不太常見的符號使用更少的位來表示。在實踐中,較小的數字最常出現。因此,如果我們可以有效地表示小數,即使表示大數的效率較低,我們也將獲得無損數據壓縮。


Uvarints 是一種使用一個或多個字節序列化無符號整數的方法。較小的數字占用較少的字節數。uvarint 中的每個字節,除了最后一個字節,都設置了最高有效位 (msb)——這表明還有更多的字節要來。每個字節的低 7 位用于以 7 位為一組存儲數字,最低有效組在前。我們可以對任意位數的無符號整數執行此操作。


例如,


uint bits : uvarint bytes

7 7f : 1 7f 

14 3fff : 2 ff7f 

21 1fffff : 3 ffff7f 

28 fffffff : 4 ffffff7f 

35 7ffffffff : 5 ffffffff7f 

42 3ffffffffff : 6 ffffffffff7f 

49 1ffffffffffff : 7 ffffffffffff7f 

56 ffffffffffffff : 8 ffffffffffffff7f 

63 7fffffffffffffff : 9 ffffffffffffffff7f 

64 ffffffffffffffff : 10 ffffffffffffffffff01 

依此類推,對于我們想要的盡可能多的 uint 位。


如果我們有很多數字表示為 1 到 49 位的無符號 64 位整數序列化為 1 到 7 個字節的 uvarints,我們不會關心是否有一些數字表示為 57 到 64 位序列化為 9 到 10 個字節的 uvarint 的無符號 64 位整數。


查看完整回答
反對 回復 2021-08-10
  • 2 回答
  • 0 關注
  • 287 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號