0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Google二進(jìn)制編解碼技術(shù)之Protobuf 3

jf_78858299 ? 來(lái)源:碼農(nóng)的荒島求生 ? 作者:陸小風(fēng) ? 2023-02-15 14:29 ? 次閱讀
字段名稱與字段類(lèi)型

對(duì)于任何一個(gè)有用的信息都包含這樣幾部分:

  • 字段名稱
  • 字段類(lèi)型
  • 字段值

就像C/C++中定義變量時(shí):

int i = 100;

在這里,字段名稱就是i,字段類(lèi)型是int,字段值是100。

剛才我們用varint以及ZigZag編碼解決了字段值表示的問(wèn)題,那么該怎樣表示字段名稱和字段類(lèi)型呢?

首先,對(duì)于字段類(lèi)型還比較簡(jiǎn)單,因?yàn)樽侄晤?lèi)型就那么多,protobuf中定義了6種字段類(lèi)型:

圖片

對(duì)于6種字段類(lèi)型我們使用3個(gè)比特位來(lái)表示就足夠了。

接下來(lái)比較有趣的是字段名稱該怎么表示呢?假設(shè)我們需要傳遞這樣一個(gè)字段:

int long_long_name = 100;

那么我們真的需要把“l(fā)ong_long_name”這么多字符通過(guò)網(wǎng)絡(luò)傳遞給對(duì)端嗎?

既然通信雙方需要協(xié)議,那么“l(fā)ong_long_name”這字段其實(shí)是client和server都知道的,它們唯一不知道的就是“ 哪些值屬于哪些字段 ”。

為解決這個(gè)問(wèn)題, 我們給每個(gè)字段都進(jìn)行編號(hào) ,比如通信雙方都知道“l(fā)ong_long_name”這個(gè)字段的編號(hào)是2,那么對(duì)于:

int long_long_name = 100;

這個(gè)信息我們只需要傳遞:

  • 字段名稱:2 (2對(duì)應(yīng)字段“l(fā)ong_long_name”)
  • 字段類(lèi)型:0 (0表示varint類(lèi)型,參見(jiàn)上圖)
  • 字段值:100

所以我們可以看到, 無(wú)論你用多么復(fù)雜的字段名稱也不會(huì)影響編碼后占據(jù)的空間,字段名稱根本就不會(huì)出現(xiàn)在編碼后的信息中, so clever。

從宏觀上看

我們已經(jīng)在protobuf中看到了數(shù)字以及字段名稱以及字段類(lèi)型是怎么表示了,現(xiàn)在是時(shí)候從宏觀角度來(lái)看看多個(gè)字段該怎么編碼了。

從本質(zhì)上講,protobuf被編碼后形成一系列的key-value,每個(gè)key-value對(duì)應(yīng)一個(gè)proto中的字段。

也就是鍵值對(duì):

圖片

其中value比較簡(jiǎn)單,也就是字段值;而字段名稱和字段類(lèi)型會(huì)被拼接成key,protobuf中共有6種類(lèi)型,因此只需要3個(gè)比特位即可;字段名稱只需要存儲(chǔ)對(duì)應(yīng)的編號(hào),這樣可以就可以這樣編碼:

(字段編號(hào) << 3) | 字段類(lèi)型

假設(shè)server接收到了一個(gè)key為0x08,其二進(jìn)制的表示為:

0000 1000

由于key也是利用varint編碼的,因此需要將第一個(gè)比特位去掉,這樣我的得到:

000 1000

根據(jù)key的編碼方式,其后三個(gè)比特位表示字段類(lèi)型,即:

000

也就是0,這樣我們知道該key的類(lèi)型是Varint(第0號(hào)類(lèi)型),而字段編號(hào)為抹掉后3個(gè)比特位的值,即:

0001

這樣,我們就知道了該key對(duì)應(yīng)的字段編號(hào)為1,得到編號(hào)我們就能根據(jù)編號(hào)找到對(duì)應(yīng)的編號(hào)名稱。

嵌套數(shù)據(jù)

與Json和XML類(lèi)似,protobuf中也支持嵌套消息,就像這樣:

message SubMsg {
  optional int32 id = 1;
}
message Msg {
  optional SubMsg msg = 1;
}

其實(shí)現(xiàn)也比較簡(jiǎn)單,這依然遵循被編碼后形成一系列的key-value,只不過(guò)對(duì)于嵌套類(lèi)型的key來(lái)說(shuō),其value是由子消息的key-value組成。

圖片

protobuf與編譯語(yǔ)言

與Json一樣,protobuf也是一門(mén)語(yǔ)言,兼具了文本的可讀性以及二進(jìn)制的高效。

protobuf之所以能做到這一點(diǎn)就好比C語(yǔ)言與機(jī)器指令。

C語(yǔ)言是給程序員看的,可讀性好,而機(jī)器指令是給硬件使用的,性能好,編譯器會(huì)將C語(yǔ)言程序轉(zhuǎn)為機(jī)器可執(zhí)行的機(jī)器指令。

而protobuf也一樣,protobuf也是一門(mén)語(yǔ)言,會(huì)將可讀性較好的消息編碼為二進(jìn)制從而可以在網(wǎng)絡(luò)中進(jìn)行傳播,而對(duì)端也可以將其解碼回來(lái)。

在這里protobuf中定義的消息就好比C語(yǔ)言,編碼后的二進(jìn)制消息就好比機(jī)器指令。

而protobuf作為事實(shí)上語(yǔ)言必然有自己的語(yǔ)法,其語(yǔ)法就是這樣:

圖片

怎么樣,還覺(jué)得編譯原理沒(méi)什么用嗎?

不理解編譯原理是不可能發(fā)明protobuf這種技術(shù)的。

總結(jié)

我在寫(xiě)這篇文章時(shí)不斷感嘆,Google的這項(xiàng)技術(shù)節(jié)省了多少程序員的時(shí)間,同時(shí)我們也能看到這種基石般的技術(shù)依賴的底層原理卻非常古老:

  • 信息的編解碼
  • 編譯原理

怎么樣,這些是不是遠(yuǎn)遠(yuǎn)沒(méi)有IT界各種流行的技術(shù)聽(tīng)上去時(shí)髦有趣,而正是這種樸素的技術(shù)支撐起了工業(yè)界,現(xiàn)在你也應(yīng)該能明白底層技術(shù)的重要性了吧。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 計(jì)算機(jī)
    +關(guān)注

    關(guān)注

    19

    文章

    7300

    瀏覽量

    87547
  • Server
    +關(guān)注

    關(guān)注

    0

    文章

    90

    瀏覽量

    23967
  • 網(wǎng)絡(luò)編程
    +關(guān)注

    關(guān)注

    0

    文章

    66

    瀏覽量

    10048
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    探討2對(duì)4二進(jìn)制解碼器及4到16二進(jìn)制解碼器配置

    為等效代碼。 二進(jìn)制解碼器是另一種類(lèi)型的數(shù)字邏輯設(shè)備,根據(jù)數(shù)據(jù)輸入線的數(shù)量,其輸入的2位,3位或4位代碼,因此具有一組2位或更多位的解碼器將定義為具有n位代碼,因此將有可能表示2 n個(gè)
    的頭像 發(fā)表于 12-29 12:10 ?1w次閱讀
    探討2對(duì)4<b class='flag-5'>二進(jìn)制</b><b class='flag-5'>解碼</b>器及4到16<b class='flag-5'>二進(jìn)制</b><b class='flag-5'>解碼</b>器配置

    二進(jìn)制相對(duì)調(diào)相(二進(jìn)制差分調(diào)相2DPSK)的工作原理

    二進(jìn)制相對(duì)調(diào)相(二進(jìn)制差分調(diào)相2DPSK)的工作原理
    發(fā)表于 10-21 13:01 ?3173次閱讀
    <b class='flag-5'>二進(jìn)制</b>相對(duì)調(diào)相(<b class='flag-5'>二進(jìn)制</b>差分調(diào)相2DPSK)的工作原理

    二進(jìn)制

    二進(jìn)制   二進(jìn)制與十進(jìn)制的區(qū)別在于數(shù)碼的個(gè)數(shù)和進(jìn)位規(guī)律有很大的區(qū)別,顧名思義,二進(jìn)制的計(jì)數(shù)規(guī)律為逢二進(jìn)一,是以2為基數(shù)的計(jì)數(shù)體制。10這
    發(fā)表于 04-06 23:48 ?8140次閱讀
    <b class='flag-5'>二進(jìn)制</b>

    二進(jìn)制變化彩燈

    二進(jìn)制變化彩燈
    發(fā)表于 04-09 17:52 ?1361次閱讀
    <b class='flag-5'>二進(jìn)制</b>變化彩燈

    二進(jìn)制時(shí)鐘電路

    二進(jìn)制時(shí)鐘電路
    發(fā)表于 09-11 11:22 ?3088次閱讀
    <b class='flag-5'>二進(jìn)制</b>時(shí)鐘電路

    二進(jìn)制編碼和二進(jìn)制數(shù)據(jù)

    二進(jìn)制編碼和二進(jìn)制數(shù)據(jù)   二進(jìn)制編碼是計(jì)算機(jī)內(nèi)使用最多的碼制,它只使用兩個(gè)基本符號(hào)"0"和"1",并且通過(guò)由這兩個(gè)符號(hào)組成的
    發(fā)表于 10-13 16:22 ?4735次閱讀

    什么是二進(jìn)制計(jì)數(shù)器,二進(jìn)制計(jì)數(shù)器原理是什么?

    什么是二進(jìn)制計(jì)數(shù)器,二進(jìn)制計(jì)數(shù)器原理是什么? 計(jì)數(shù)器是數(shù)字系統(tǒng)中用得較多的基本邏輯器件。它不僅能記錄輸入時(shí)鐘脈沖的個(gè)數(shù),還可以實(shí)現(xiàn)
    發(fā)表于 03-08 13:16 ?3.1w次閱讀

    二進(jìn)制電平,什么是二進(jìn)制電平

    二進(jìn)制電平,什么是二進(jìn)制電平 在二進(jìn)制數(shù)字通信系統(tǒng)中,每個(gè)碼元或每個(gè)符號(hào)只能是“1”和“0”兩個(gè)狀態(tài)之一。若將每個(gè)碼元可能取的狀態(tài)增
    發(fā)表于 03-17 16:51 ?2333次閱讀

    二進(jìn)制加法程序【匯編版】

    二進(jìn)制加法程序【匯編版】二進(jìn)制加法程序【匯編版】二進(jìn)制加法程序【匯編版】二進(jìn)制加法程序【匯編版】
    發(fā)表于 12-29 11:02 ?0次下載

    二進(jìn)制加法程序【C語(yǔ)言版】

    二進(jìn)制加法程序【C語(yǔ)言版】二進(jìn)制加法程序【C語(yǔ)言版】二進(jìn)制加法程序【C語(yǔ)言版】二進(jìn)制加法程序【C語(yǔ)言版】
    發(fā)表于 12-29 11:03 ?0次下載

    3二進(jìn)制計(jì)數(shù)器

    基于VHDL的EDA實(shí)驗(yàn)---3二進(jìn)制計(jì)數(shù)器
    發(fā)表于 11-08 17:45 ?1次下載

    二進(jìn)制數(shù)據(jù)壓縮算法

    二進(jìn)制數(shù)據(jù)壓縮算法二進(jìn)制是計(jì)算技術(shù)中廣泛采用的一種數(shù)制。二進(jìn)制數(shù)據(jù)是用0和1兩個(gè)數(shù)碼來(lái)表示的數(shù)。它的基數(shù)為2,進(jìn)位規(guī)則是“逢二進(jìn)一”,借位規(guī)
    的頭像 發(fā)表于 02-28 09:31 ?2w次閱讀

    二進(jìn)制解碼器案例說(shuō)明

    二進(jìn)制解碼器是另一種由各個(gè)邏輯門(mén)構(gòu)成的組合邏輯電路,與編碼器完全相反。
    的頭像 發(fā)表于 06-22 09:41 ?9172次閱讀
    <b class='flag-5'>二進(jìn)制</b><b class='flag-5'>解碼</b>器案例說(shuō)明

    二進(jìn)制解碼器到底是什么

    二進(jìn)制解碼器是由單獨(dú)的邏輯門(mén)構(gòu)成的另一種組合邏輯電路,與編碼器完全相反。名稱“解碼器”是指將編碼信息從一種格式轉(zhuǎn)換或解碼為另一種格式,因此二進(jìn)制
    發(fā)表于 01-03 17:42 ?6160次閱讀
    <b class='flag-5'>二進(jìn)制</b><b class='flag-5'>解碼</b>器到底是什么

    二進(jìn)制解碼器開(kāi)源設(shè)計(jì)

    電子發(fā)燒友網(wǎng)站提供《二進(jìn)制解碼器開(kāi)源設(shè)計(jì).zip》資料免費(fèi)下載
    發(fā)表于 06-16 15:01 ?0次下載
    <b class='flag-5'>二進(jìn)制</b><b class='flag-5'>解碼</b>器開(kāi)源設(shè)計(jì)