protobuf編碼

?

proto2

Protocol Buffers 是一種輕便高效的結構化數據存儲格式,可以用于結構化數據序列化,適合做數據存儲或 RPC 數據交換格式。可用于通訊協議、數據存儲等領域的語言無關、平臺無關、可擴展的序列化結構數據格式。

字段規則

  • required: 字段必須存在
  • optional: 字段沒有或有一個
  • repeated: 字段重復,0個或多個

proto 數據類型

?

.proto Type
Notes
C++ Type
Java Type
Python Type[2]
Go Type
double固定8字節長度doubledoublefloat*float64
float固定4字節長度floatfloatfloat*float32
int32可變長度編碼。對負數編碼低效,如果字段可能是負數,用sint32代替int32intint*int32
int64可變長度編碼。對負數編碼低效,如果字段可能是負數,用sint64代替int64longint/long[3]*int64
uint32可變長度編碼,無符號整數uint32int[1]int/long[3]*uint32
uint64可變長度編碼,無符號整數uint64long[1]int/long[3]*uint64
sint32可變長度編碼。有符號整數。 These more efficiently encode negative numbers than regular int32s.int32intint*int32
sint64可變長度編碼。有符號整數。These more efficiently encode negative numbers than regular int64s.int64longint/long[3]*int64
fixed32固定4字節長度,無符號整數。 More efficient than uint32 if values are often greater than 228.uint32int[1]int/long[3]*uint32
fixed64固定8字節長度,無符號整數。 More efficient than uint64 if values are often greater than 256.uint64long[1]int/long[3]*uint64
sfixed32固定4字節長度,有符號整數int32intint*int32
sfixed64固定8字節長度,有符號整數int64longint/long[3]*int64
bool?boolbooleanbool*bool
stringUTF-8 encoded or 7-bit ASCII text.stringStringstr/unicode[4]*string
bytes包含任意字節序列stringByteStringstr[]byte

編碼規則

1.varints

理解簡單protobuf編碼,首先要知道varints。varints使用一個字節或多個字節對整數序列化方法。

varints中的每個字節除了最后一個字節,有一個最有效位(most significant bit ,msb),這意味指示之后有其他字節。每個字節的低7位一組數的補碼

例如:

1

0000? 0001

300

1010? 1100? 0000? 0010

只取每個字節低七位

010? 1100? 000? 0010

小端序->大端序

000? 0010? 010? 1100 -->? 0001? 0010? 1100? =300

?

2.消息結構

protobuf 消息是一系列key-value對,對于二進制消息,字段數字作為關鍵字。字段的命名和類型在解碼時確定。

在進行消息編碼時,key/value被連接成字節流。在解碼時,解析器可以直接跳過不識別的字段,這樣就可以保證新老版本消息定義在新老程序之間的兼容性,從而有效的避免了使用older消息格式的older程序在解析newer程序發來的newer消息時,一旦遇到未知(新添加的)字段時而引發的解析和對象初始化的錯誤。最后,我們介紹一下字段標號和字段類型是如何進行編碼的。每一個 wire-format消息的key實際上是有兩個值組成:proto文件中定義的字段標號和wire type。

Type
Meaning
Used For
0Varintint32, int64, uint32, uint64, sint32, sint64, bool, enum
164-bitfixed64, sfixed64, double
2Length-delimitedstring, bytes, embedded messages, packed repeated fields
3Start groupgroups (deprecated)
4End groupgroups (deprecated)
532-bitfixed32, sfixed32, float

key =?(field_number << 3) | wire_type?key的最后3個bits用于存儲字段的類型信息。那么在使用該編碼時,Protocol Buffer所支持的字段類型將不會超過8種。

例如:150(十進制) 在protobuf二進制文件中是 08 96 01

08 --> 00001000? field_number=1,wire_type=0

96 01 -> 1001 0110? 0000 0001 -->? 001 0110? ?000? 0001? -->? 000 0001? ?001? 0110? ?--> 1001? 0110 =150

3.Signed Integers

wire_type=0 的類型都以varint 進行編碼,所以對于int32和int64,對于負數使用補碼,int32 需要5個字節,int64需要10個字節,有符號整數使用ZIgZag編碼

ZigZag 將有符號整數映射到無符號整數,以此得到一個絕對值較小的數字(例如-1)j就可以獲得一個較小的varint編碼值。

?

?

Signed Original
Encoded As
00
-11
12
-23
21474836474294967294
-21474836484294967295

sint32:? ? ? ?(n?<<?1)?^?(n?>>?31)

?sint64:? ? ? ?(n?<<?1)?^?(n?>>?63)

4.Non-varint Numbers

wire-type=1:fixed64, sfixed64, double 固定64bit

wire-type=5:fixed32, sfixed32, float,固定32bit

5.Strings

wire-type=2,字符串長度使用varint編碼

例如

message Test2 {optional string b = 2;
}

b=“testing” ,編碼后結果:

12 07 74 65 73 74 69 6e 67

12: field number=2,wire-type=2? (2<< 3)|2=0x12

長度為7 varint編碼 0x07

74 65 73 74 69 6e 67 ?UTF8?編碼

6.Embedded Messages嵌套消息

wire-type=2
message Test1 {optional int32 a = 1;
}
message Test3 {optional Test1 c = 3;
}

Test1's?a?field set to 150

Test3 編碼結果:?1a 03 08 96 01

1a: field_number=3,wire_type=2? (3<< 3)|2=11010=0x1a

03: 字節數

08 96 01 : c編碼結果

7.Optional And Repeated Elements

proto2 :消息被定義repeated (沒有 [packed=true]選項),編碼的消息有0或多個使用相同字段標號的key-value對,這些重復的值不必連續出現;?他們可能會與其他字段交錯,但在解碼時順序保留

optional字段,編碼后的消息可能有也可能沒有包含該字段號的鍵值對。

proto3 使用packed encoding:

包含零個元素的打包重復字段不會出現在編碼消息中。這個字段的所有元素都打包到一個wire-type=2的key-value對中

?

message Test4 {repeated int32 d = 4 [packed=true];
}
22        // key (field number 4, wire type 2)
06        // payload size (6 bytes)
03        // first element (varint 3)
8E 02     // second element (varint 270)
9E A7 05  // third element (varint 86942)

proto2默認不設置 packed=true
repeated編碼采用空格(0x20)分隔
結果是20 03 20 8e 02 20 9e a7? 05

轉載于:https://www.cnblogs.com/dj0325/p/9238025.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/280009.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/280009.shtml
英文地址,請注明出處:http://en.pswp.cn/news/280009.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

定制.NET 6.0的Middleware中間件

大家好&#xff0c;我是張飛洪&#xff0c;感謝您的閱讀&#xff0c;我會不定期和你分享學習心得&#xff0c;希望我的文章能成為你成長路上的墊腳石&#xff0c;讓我們一起精進。在本文中&#xff0c;我們將學習中間件&#xff0c;以及如何使用它進一步定制應用程序。我們將快…

Python-循環控制--個人課堂筆記

Python中的兩種循環方式&#xff08;目前學到&#xff09;&#xff1a;for循環和while循環 for循環和while循環的區別&#xff1a; for循環一般用于控制循環的次數&#xff0c;while循環則是條件循環。 操作實例-猜數字小游戲&#xff08;3次猜錯提示游戲結束&#xff09;&…

刪除microsoft_如何從您的Microsoft帳戶中刪除設備

刪除microsoftWhen you sign into Windows 8 or 10 using your Microsoft account (and other Microsoft devices, like an Xbox), those devices become associated with your account. If you want to remove an old device you’ve gotten rid of, you’ll have to pay a vi…

線程的語法 (event,重要)

Python threading模塊 2種調用方式 直接調用 12345678910111213141516171819import threadingimport timedef sayhi(num): #定義每個線程要運行的函數print("running on number:%s" %num)time.sleep(3)if __name__ __main__:t1 threading.Thread(targetsayhi,args(…

求最大值和下標值

本題要求編寫程序&#xff0c;找出給定的n個數中的最大值及其對應的最小下標&#xff08;下標從0開始&#xff09;。 輸入格式: 輸入在第一行中給出一個正整數n&#xff08;1<n≤10&#xff09;。第二行輸入n個整數&#xff0c;用空格分開。 輸出格式: 在一行中輸出最大值及…

windows應用商店修復_如何修復Windows應用商店中的卡死下載

windows應用商店修復Though it’s had its share of flaky behavior since being introduced in Windows 8, the Windows Store has gotten more reliable over time. It still has the occasional problems, though. One of the more irritating issues is when an app update…

OpenWrt:Linux下生成banner

Linux下有三個小工具可以生成banner&#xff1a;1、banner使用#生成banner&#xff1b;2、figlet使用一些普通字符生成banner&#xff1b;3、toilet使用一些復雜的彩色特殊字符生成banner。使用apt-get安裝的時候需要輸入以下命令&#xff1a; $ sudo apt-get install sysvbann…

新冠病毒中招 | 第二天

今天跟大家分享我個人感染奧密克戎毒株第二天的經歷和感受。早上7點多自然醒來&#xff0c;已經沒有四肢乏力的感覺&#xff0c;但是身體的本能還是告訴我不愿意動彈。由于第一天躺著睡了一天&#xff0c;確實是躺得腰酸背疼的。起床量了一下體溫36.4正常&#xff0c;決定今天不…

輸出到Excel

HSSFWorkbook oBook new HSSFWorkbook(); NPOI.SS.UserModel.ISheet oSheet oBook.CreateSheet(); #region 輸出到Excel MemoryStream ms new MemoryStream(); oBook.Write(ms);string sExportPath ""; using (SaveFileDialog saveFileDialog1 new SaveFileDial…

JavaScript 精粹 基礎 進階(5)數組

轉載請注明出處 原文連接 blog.huanghanlian.com/article/5b6… 數組是值的有序集合。每個值叫做元素&#xff0c;每個元素在數組中都有數字位置編號&#xff0c;也就是索引。JS中的數組是弱類型的&#xff0c;數組中可以含有不同類型的元素。數組元素甚至可以是對象或其它數組…

icloud 購買存儲空間_如何釋放iCloud存儲空間

icloud 購買存儲空間Apple offers 5 GB of free iCloud space to everyone, but you’ll run up against that storage limit sooner than you’d think. Device backups, photos, documents, iCloud email, and other bits of data all share that space. Apple為每個人提供5 …

基于LAMP實現web日志管理查看

前言&#xff1a;日志是一個重要的信息庫&#xff0c;如何高效便捷的查看系統中的日志信息&#xff0c;是系統管理員管理系統的必備的技術。實現方式&#xff1a;1、將日志存儲于數據庫。2、采用LAMP架構&#xff0c;搭建PHP應用&#xff0c;通過web服務訪問數據庫&#xff0c;…

WPF效果第二百零七篇之EditableSlider

前面簡單玩耍一下快速黑白灰效果; 今天又玩了一下ZoomBlurEffect,來看看最終實現的效果:1、ps和cs文件都在Shazzam中,咱們自己隨意玩耍;今天主角是下面這位:2、來看看自定義控件布局(TextBox、Slider、ToggleButton)&#xff1a;3、點擊編輯按鈕,我就直接偷懶了:private void E…

閑話高并發的那些神話,看京東架構師如何把它拉下神壇

轉載:閑話高并發的那些神話&#xff0c;看京東架構師如何把它拉下神壇 高并發也算是這幾年的熱門詞匯了&#xff0c;尤其在互聯網圈&#xff0c;開口不聊個高并發問題&#xff0c;都不好意思出門。高并發有那么邪乎嗎&#xff1f;動不動就千萬并發、億級流量&#xff0c;聽上去…

c# Clone方法

clone是深拷貝&#xff0c;copy是淺拷貝&#xff0c;如果是值類型的話是沒什么區別的&#xff0c;如果是引用類型的話深拷貝拷貝的事整個對象的數據&#xff0c;而淺拷貝僅僅拷貝對象的引用。因為類的實例是引用類型&#xff0c;要想用原有的類中的實例的數據的話&#xff0c;既…

使用MyQ打開車庫門時如何接收警報

Chamberlain’s MyQ technology is great for opening and closing your garage door remotely with your smartphone, but you can also receive alerts whenever your garage door opens and closes (as well as receive alerts when it’s been open for an extended amount…

踏實工作,實現價值

工作&#xff0c;為實現自我價值 若想在漫長的職場生涯中穩步高升&#xff0c;首先要踏踏實實&#xff0c;專心致志、充滿激情的去完成工作中的每一項任務&#xff0c;無論工作是繁重的還是瑣碎的&#xff0c;都要嚴格要求自己全身心的去完成。而不是一味的抱怨&#xff0c;一味…

mac 防火墻禁止程序聯網_如何允許應用程序通過Mac的防火墻進行通信

mac 防火墻禁止程序聯網If you use a Mac, chances are you might not even realize that OS X comes with a firewall. This firewall helps ensure unauthorized app and services can’t contact your computer, and prevents intruders from sniffing out your Mac on a ne…

WPF-22 基于MVVM員工管理-02

我們接著上一節&#xff0c;這節我們實現crud操作&#xff0c;我們在EmployeeViewMode類中新增如下成員&#xff0c;并在構造函數中初始化該成員code snippetpublic EmployeeViewMode() {employeeService new EmployeeService();BindData();Employee new Employee();AddComma…

linux 3

-- Linux -- 開心的一天 vi   所有的 unix like 系統都會內置 vi 文本編輯器 vim  較多使用的,可以主動的以字體顏色辨別語法的正確性&#xff0c;方便程序設計 vi/vim 的使用 -- 命令模式&#xff08;Command mode&#xff09; 輸入模式&#xff08;Insert mode&#x…