protobuf編解碼

基本原理:

1.可變長度編碼 & 跳過可選字段

2.作用在網(wǎng)絡傳輸過程

一涎显、存儲方式

TAG? [LENGTH]? VALUE

TAG:? filedId(前五位bit)+ WIRE_TYPE(低三位bit)? ? 1 byte?

LENGTH: WIRE_TYPE = 2 時 存在? ? ? 1byte

VALUE:WIRE_TYPE = varint 時 采用小端存儲模式,其他正常讀取?

二悼尾、WIRE_TYPE

0: varint變長編碼,主要就是依靠這個來減小存儲體積

1:定長 8byte

2: 指定長度

3隘庄、4 :已廢棄

5:定長 4 byte

三曹铃、Varint 原理

int32 類型的數(shù)字,一般需要 4 個 byte 來表示总放。但是采用 Varint,對于很小的 int32 類型的數(shù)字好爬,則可以用 1 個 byte 來表示局雄。

采用 Varint 表示法,大的數(shù)字則需要 5 個 byte 來表示存炮。從統(tǒng)計的角度來說炬搭,一般不會所有的消息中的數(shù)字都是大數(shù),因此大多數(shù)情況下穆桂,采用 Varint 后宫盔,可以用更少的字節(jié)數(shù)來表示數(shù)字信息

小端存儲模式

示例1:

對于數(shù)字1 對應的二進制是 :00000000 00000000 00000000 00000001

PB 只用一個字節(jié)就可以存儲該值:即 0 00000001

第一位0 表示該字節(jié)就是結束字節(jié),后七位 0000001 即表示十進制的數(shù)字 1

示例2:

對于數(shù)字 500享完,對應的二進制:00000000 00000000 00000001 11110100

? ? ? ? 從最低位開始 七位分割 即:1110100 0000011

? ? ? ? PB編碼用兩個字節(jié)表示 :1 1110100 0 0000011

? ? ? ? 解碼:高位是 1 表示 還要讀后面一個字節(jié)

? ? ? ? 去掉最高位:1110100 0000011

? ? ? ? 由于是小端模式:組合后是 00000111110100 十進制即是500

三飘言、zigTag 編碼(解決負數(shù)占用多字節(jié)問題)

原碼:最高位為符號位,剩余位表示絕對值驼侠;

反碼:除符號位外姿鸿,對原碼剩余位依次取反;

補碼:對于正數(shù)倒源,補碼為其自身苛预;對于負數(shù),除符號位外對原碼剩余位依次取反然后+1

原碼缺陷:

1笋熬、 0 有兩種表現(xiàn)形式 :00000000 和 10000000

2热某、計算錯誤:1 + (-1) = 00000001 + 10000001 = 10000010 = -2

補碼解決的問題:1+(-1) = 00000001+ 11111111 = 00000000 = 0

zizag會對負數(shù)進行一輪哈希映射,拿到hash值后胳螟,編碼策略:直接去掉hash值的前導0之后的byte作為壓縮編碼

四昔馋、一些示例

示例1:

message Test1 {

? ? optional int32 a = 1; //表明是 fildId 是 1

}

創(chuàng)建 Test1消息并把a設置為150

編碼后:08 96 01

編碼后對應二進制:00001000 10010110 00000001

解碼:

(1)000001000 后三位:000 表示W(wǎng)IRE_TYPE = 0,即 Varint;00001 = 1 表示對應第一個 fieldId;

(2)10010110 00000001:

10010110 最高位 1 表示還需要讀取下一個字節(jié),剩余 0010110糖耸;

00000001 最高位表示無需讀下一個字節(jié)秘遏,剩余 0000001;

按照小端模式進行拼接:00000010010110 轉化為10進制 即 150

示例2:嵌套消息(嵌套的消息會作為WIRE_TYPE = 2 來對待)

Message Test2{

? ? ? ? optional Test1 c = 3;

}

如示例1 給Test1 a 賦值 150

則得到的編碼:1a 03 08 96 01

1a 對應 2進制:00011010 后三位表示 有線類型 2嘉竟,前五位表示 3 對應的 是fieldId

03 表示長度:及3個字節(jié)的長度

08 96 01 :見示例一分析過程

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末邦危,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子舍扰,更是在濱河造成了極大的恐慌倦蚪,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件边苹,死亡現(xiàn)場離奇詭異陵且,居然都是意外死亡,警方通過查閱死者的電腦和手機个束,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進店門慕购,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人播急,你說我怎么就攤上這事脓钾。” “怎么了桩警?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵可训,是天一觀的道長。 經(jīng)常有香客問我捶枢,道長握截,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任烂叔,我火速辦了婚禮谨胞,結果婚禮上,老公的妹妹穿的比我還像新娘蒜鸡。我一直安慰自己胯努,他們只是感情好牢裳,可當我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著叶沛,像睡著了一般蒲讯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上灰署,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天侣监,我揣著相機與錄音屿愚,去河邊找鬼敲才。 笑死孤钦,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的肴茄。 我是一名探鬼主播晌畅,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼独郎!你這毒婦竟也來了踩麦?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤氓癌,失蹤者是張志新(化名)和其女友劉穎谓谦,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贪婉,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡反粥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了疲迂。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片才顿。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖尤蒿,靈堂內(nèi)的尸體忽然破棺而出郑气,到底是詐尸還是另有隱情,我是刑警寧澤腰池,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布尾组,位于F島的核電站,受9級特大地震影響示弓,放射性物質(zhì)發(fā)生泄漏讳侨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一奏属、第九天 我趴在偏房一處隱蔽的房頂上張望跨跨。 院中可真熱鬧,春花似錦囱皿、人聲如沸勇婴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽耕渴。三九已至德谅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間萨螺,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工愧驱, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留慰技,地道東北人。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓组砚,卻偏偏與公主長得像吻商,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子糟红,可洞房花燭夜當晚...
    茶點故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內(nèi)容