最近面試中被問protobuf的加解碼原理,非常的尷尬,因為我沒了解過,這裡稍作總結
proto檔案
每乙個proto檔案其實對應著我們正常的乙個模型(也就是model),只是proto檔案是用來描述這樣的乙個模型的檔案,並非實際上的工程model。
舉個例子,檔案person.proto:
message person
來看看這個檔案,proto使用message表示乙個訊息格式,類似於一般程式語言中的class,struct。
proto使用流程
這裡就不介紹使用方式了,簡單說一下proto檔案的使用流程,為下面講解編譯碼原理做一下鋪墊
編寫proto檔案
使用工具將proto檔案轉成對應語言的model檔案(person.proto->person.swift)
安裝google提供的三方庫protobuf
呼叫轉換出來的person.swift檔案中的encode和decode方法完成編譯碼等各類工作
protobuf編譯碼
接下來講一下重點的內容
protobuf中整型資料的編碼
protobuf中採用varints編碼對整型資料進行編碼,經過varints編碼後的資料,它的每乙個位元組的高位是乙個標記位。如果標記位是1,則代表下乙個位元組仍然是當前整型資料的組成;如果標記位是0,則代表當前資料結束了。
舉個例子:
->00000001 表示數字1,因為首位是標記為表示只需要當前位元組就能表示資料了,後七位就是這個值
->10101100 00000010 表示數字300,為什麼,首先看兩個位元組的最高位,1和0,1表示該下乙個位元組還是屬於這個數字的一部分,0表示這個資料到此子節表示結束,因此真實的資料是0101100 0000010 由於採用的是小端序,所以實際計算位0000010 0101100為 256+32+8+4 = 300
還有負數編碼,因為負數採用補碼,比如-1,表示成11111111,會導致每次數值都需要位元組拉滿才能表示的了(用variant編碼),所以對於負數protobuf採用zigzag編碼公式編碼以後再使用varint編碼。
protobuf整體的編碼
protobuf的訊息是經過編碼序列化的一系列key-value對,乙個型別的資料對應乙個key-value。value就是原始資料經過編碼後的資料,而key由field number和wire type組成。其中field number是指.proto檔案中定義的資料變數的field值(也就是前面proto格式中的1和2)。wire type用於區分字段值的型別(用於區分string,int32)
即:wire_type
type
0int32、int64、uint32、uint64、sint32、sint64、bool、enum
1fixed、sfixed64、double
2string、bytes、embedded、messages、packed repeated fields
舉個例子:
key = (field_number << 3) | wire_type
比如00001000,後三位表示wiretype = 0,前五位使用varint編碼,因此field number為1,也就是id這個字段
如果我們給id設定乙個值150,那麼對應的編碼就是
08 96 01
-> 00001000 10010110 00000001
-> wiretype = 0,field number為1即字段為id以及 0000001 0010110 = 128+16+4+2 =150
protobuf中字串的編碼
字串本身使用utf8編碼,整個字串字段使用key-len-value形式儲存,
protobuf中巢狀訊息的編碼
類似於字串,採用key-len-value來儲存,len表示該欄位對應的訊息所需要的訊息長度
歸總相對來說protobuf跟json的編碼完全不同,乙個編碼到字元,乙個編碼到位元組,因此速度和資料量上有乙個質的飛躍
開發protobuf擴充套件的一些筆記
乙個需求要接入公司內部的乙個基於protobuf協議的介面,protobuf的庫檔案都是proto編譯器生成的cpp檔案。要編譯成php擴充套件的話,需要c c 混編,這裡記錄一下。1 公升級一下安裝的protobuf,貌似c1的機器上的protobuf都是2.4.0的,當編譯高階的一些語法的pro...
關於stringstream的一些總結
c 標準庫中的提供了比ansi c的更高階的一些功能,即單純性 型別安全和可擴充套件性。可以使用這些庫來實現安全和自動的型別轉換。如果你已習慣了風格的轉換,也許你首先會問 為什麼要花額外的精力來學習基於的型別轉換呢?也許對下面乙個簡單的例子的回顧能夠說服你。假設你想用sprintf 函式將乙個變數從...
關於JSON的一些總結
一 關於json json是一種類似於xml的通用資料交換格式,具有比xml更高的傳輸效率.從結構上看,所有的資料 data 最終都可以分解成三種型別 第一種型別是標量 scalar 也就是乙個單獨的字串 string 或數字 numbers 比如 北京 這個單獨的詞。第二種型別是序列 sequen...