日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Erlang 位串和二进制数据

發(fā)布時間:2023/12/18 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Erlang 位串和二进制数据 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?

http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=25876834&id=3300393

因為在本人工作中,服務(wù)端Erlang和客戶端的flash通信都是發(fā)送二進(jìn)制數(shù)據(jù)(協(xié)議)來通信,Erlang處理起來二進(jìn)制數(shù)據(jù)真的很方便,在空余時間查看和翻譯了Erlang的二進(jìn)制相關(guān)一些說明文檔,當(dāng)然里面也有根據(jù)自己的經(jīng)驗和知識理解的地方。

在二進(jìn)制解析部分,其實還有很多好的例子。還有就是Erlang的二進(jìn)制實際應(yīng)用的例子,下次會再分享的,翻譯不到位的地方,還請多多指正,原文地址 http://www.erlang.org/doc/programming_examples/bit_syntax.html#id64786, http://www.erlang.org/doc/reference_manual/expressions.html#id79300

點擊(此處)折疊或打開

  • Erlang 位串和二進(jìn)制數(shù)據(jù)
  • ? ? 位串(bitstring)是由一些有比特(bit,理解為‘位’)組成,不要求包含的比特數(shù)量能夠整除8,如果恰好能夠整除8的話,那么這個位串就是個binary。
  • 位串中的每一個位都位于確定的一個段中,一個段由一串連續(xù)的位組成(段之間沒有界限),如首位是第一個段,緊接著就是第二個段。
  • 下面的例子演示了二進(jìn)制數(shù)據(jù)的構(gòu)造,匹配,還有如何獲取和使用二進(jìn)制數(shù)據(jù)中的元素。
  • 1. 一些簡單的例子
  • 例一
  • ? ? 一個二進(jìn)制數(shù)據(jù)由一組常量或者簡單字符串構(gòu)成
  • Bin11?=?<<1,?17,?42>>,
  • Bin12?=?<<"abc">>
  • 產(chǎn)生的二進(jìn)制數(shù)據(jù)大小為3,binary_to_list(Bin11)計算結(jié)果是[1,?17,?42],?binary_to_list(Bin22)計算結(jié)果是?[97,?98,?99].
  • 例二
  • ? ? 類似的,一個二進(jìn)制數(shù)據(jù)也可以由一組已綁定的變量構(gòu)成
  • A?=?1,?B?=?17,?C?=?42,
  • Bin2?=?<<A,?B,?C:16>>
  • 產(chǎn)生的二進(jìn)制數(shù)據(jù)大小為4,binary_to_list(Bin2)計算結(jié)果是?[1,?17,?0,?42]。這里C使用了尺寸表達(dá)式(size expression),指定了C這個段在二進(jìn)制數(shù)據(jù)中占用16位,也就是兩個單位長度。
  • 例三
  • ? ? 二進(jìn)制數(shù)據(jù)也可以進(jìn)行匹配操作。假設(shè)D,E,F是自由變量,Bin2為例二中的變量:
  • ?<<D:16,?E,?F/binary>>?=?Bin2
  • 結(jié)果 D?=?273,(因為D包含了A,B兩個段,二進(jìn)制轉(zhuǎn)換為10進(jìn)制之后的結(jié)果),E?=?0,F?=?42(這里在我的機(jī)器上是?<<*>>,我的erlang版本比文檔上的版本新)
  • 2.注意
  • ? ? 語法上應(yīng)該要注意的地方,?"B=<<1>>"?這樣的寫法會被erlang編譯器理解為?"B =< <1>>"?,這樣就會產(chǎn)生語法錯誤。正確的寫法應(yīng)該是?"B = <<1>>"?。
  • 3.二進(jìn)制數(shù)據(jù)各個部分介紹
  • ? ? 位串中,每一個段都遵循通用的語法格式,如下:
  • Value:Size/TypeSpecifierList 值:大小/類型
  • 因為Size和TypeSpeciferList不是必須指明的,所以在書寫的時候它們可以省略,下面的格式是正確的:
  • Value
  • Value:Size
  • Value/TypeSpecifierList
  • 當(dāng)沒有指明使用什么規(guī)范時,就使用默認(rèn)值(默認(rèn)規(guī)范,也可以理解為默認(rèn)語法約定)。默認(rèn)值會在下面解釋
  • 在構(gòu)造二進(jìn)制數(shù)據(jù)結(jié)構(gòu)的時候,Value可以是任何表達(dá)式;在進(jìn)行二進(jìn)制的匹配操作時,Value必須是一個普通的單詞(literal?)或者變量。
  • Size?指明該段占多少位,要是指明了 TypeSpecifierList (類型),Size表示的多少個單位長度,size必須是整數(shù)。
  • TypeSpecifierList 由 ‘-’ 隔開的一組屬性組成,可以由四個部分構(gòu)成:
  • ????Type?類型,可以是 Integer,?Float,?Binary
  • ????Signedness 規(guī)定是無符號還是有符號
  • ????Endianness 規(guī)定字節(jié)存儲序列
  • ????Unit 單位長度,必須能被Size 整除
  • 如:
  • ????X:4/little-signed-integer-unit:8
  • ????X 的總大小是 4?*?8?=?32 bit啰
  • 4.默認(rèn)(約定)
  • ? ? 二進(jìn)制中每個段的數(shù)據(jù)類型默認(rèn)是整型,默認(rèn)的類型不依賴于值,即便值是一個單詞。
  • 類似的,?"<<3.14>>"?的類型也是整型,不是浮點型。
  • ??默認(rèn)的大小(Size)由類型決定,整型是8,浮點是64,如果是binary類型的話就是該binary的整個長度。在匹配操作中,只有最后一段數(shù)據(jù)使用默認(rèn)大小才是合法的,其他位置的數(shù)據(jù)段必須指定大小。
  • ??默認(rèn)的單位長度,整型和浮點都是1,binary是8.
  • ??默認(rèn)是無符號
  • ??默認(rèn)的字節(jié)序列是大頭排列
  • 5.構(gòu)造一個binary 和 位串(bitstring)
  • ? ? 構(gòu)造二進(jìn)制的語法和創(chuàng)建列表和元組不一樣,如果參數(shù)錯誤的話,會爆出 “badarg”的錯誤。
  • ? ? 一個二進(jìn)制可以由一個或多個段構(gòu)成,0個段 “<<>>”表示大小為零的二進(jìn)制數(shù)據(jù)(很多時候,我們會發(fā)空 ? ? 的二進(jìn)制作為觸發(fā)沒個事件的信號)。
  • ? ?<<Bin/binary,Bitstring/bitstring>>
  • ? ? 這樣一個數(shù)據(jù),Bin的大小一定是8比特的整數(shù)倍,而Bitstring的大小一定是1的整數(shù)倍。
  • ? ? 下面的數(shù)據(jù):
  • ????<<X:1,?Y:6>>?
  • ????可以成功構(gòu)造一個大小為7bit的位串,特別的提出一點:
  • ????<<X+1:8>>?是錯誤的,應(yīng)該寫作:
  • ????<<(X+1):8>>
  • ? ? <<"hello">>?等價于?<<$h,$e,$l,$l,$o>>?,前者在語法上比后者更加便利(語法糖)
  • 6.二進(jìn)制數(shù)據(jù)的匹配操作
  • ????匹配操作的時候,記住Size一定是一個整數(shù)或者綁定的變量(值為整數(shù)),如
  • ????foo(N,?<<X:N,T/binary>>)?->
  • ????{X,T}.
  • ????這樣是錯誤的,因為在編譯的時候,N作為Size還沒有綁定。
  • ????正確的做法:
  • ????foo(N,?Bin)?->
  • ???????<<X:N,T/binary>>?=?Bin,
  • ???????{X,T}.
  • 7.獲取一個二進(jìn)制和位串的剩余部分
  • ? ? foo(<<A:8,Rest/binary>>)?->?
  • ? ? ? ?Rest的大小一定能整除8
  • ? ? foo(<<A:8,Rest/bitstring>>)?->
  • ? ? ? ?Rest的大小沒有嚴(yán)格限制了
  • 8.位串解析(Bit String Comprehensions)
  • ? ? 位串解析類似列表解析,是一種非常高效的產(chǎn)生新的位串的方法,一般語法如下:
  • ? ? <<?BitString?||?Qualifier1,...,QualifierN?>>
  • ? ? BitString一個合法的位串表達(dá)式,Qualifier是位串生成器或者過濾器
  • ? ? 一般的生成器(如列表解析里面),通常寫作:
  • ????? Pattern?<-?ListExpr.?
  • ? ? 而位串生成器寫作:
  • ?????BitstringPattern?<=?BitStringExpr.?
  • ? ? 當(dāng)然了,這里BitStringExpr 肯定一個合法的位串表達(dá)式
  • ? ??
  • ? ? 過濾器是一個返回true或false的表達(dá)式
  • ? ? 具體的例子:
  • ? ? <<?<<?(X*2)?>>?||?<<X>>?<=?<<?1,2,3?>>?>>.
  • ? ? <<2,4,6>>
  • 1.BIF:
  • BIF:(built-in function)內(nèi)建函數(shù),是erlang語言的組成部分。是erlang虛擬機(jī)中的基本操作。
  • tuple_to_list/1將元組轉(zhuǎn)換為列表,time/0返回當(dāng)前時間的時,分,秒。
    1> tuple_to_list({12,cat,”ddd”}).
    [12,cat,"ddd"]
    3> time().
    {12,35,57}

    2.二進(jìn)制數(shù)據(jù):
    一種數(shù)據(jù)類型,用來實現(xiàn)原始數(shù)據(jù)的高速存儲。節(jié)省內(nèi)存,輸入輸出更加高效。書寫打印時,二進(jìn)制數(shù)據(jù)以一個整數(shù)或者字符序列的形式出現(xiàn),兩端分別用尖括號括起來。其中的整數(shù),每一個都要在0-255之間,如果二進(jìn)制數(shù)據(jù)是可以打印的字符串,shell將顯示字符串形式,否則會顯示一串整數(shù)。

    @spec 描述函數(shù)的參數(shù)和返回類型。類型標(biāo)注,不是erlang代碼而是注釋文檔的一部分,shell中不能使用這些標(biāo)注。erlang中的模塊聲明也是注釋的一部分。

    erlang通過BIF來構(gòu)造二進(jìn)制數(shù)據(jù)或者從中提取數(shù)據(jù),或者通過比特語法來完成這一過程。
    @spec list_tbo_inary(IoList) -> binary()
    @spec split_binary(Bin,Pos) -> {Bin1,Bin2}
    @spec term_to_binary(Term) -> Bin
    @spec binary_to_term(Bin) -> Term
    list_tbo_inary將IoList中所有東西轉(zhuǎn)換為一個二進(jìn)制數(shù)據(jù)。split_binary在pos位置將二進(jìn)制數(shù)據(jù)分割成兩個部分。下面兩個是互逆。

    4> Bin1 = <<1,2,3>>.
    <<1,2,3>>
    5> Bin2 = <<4,5>>.
    <<4,5>>
    6> Bin3 = <<6>>.
    <<6>>
    7> list_to_binary([Bin1,1,[2,3,Bin2],4|Bin3]).
    <<1,2,3,1,2,3,4,5,4,6>>
    12> split_binary(<<1,2,3,1,2,3,4,5,4,6>>,4).
    {<<1,2,3,1>>,<<2,3,4,5,4,6>>
    14> term_to_binary({11,’333a’,use}).
    <<131,104,3,97,11,100,0,4,51,51,51,97,100,0,3,117,115,101>>
    15> binary_to_term(<<131,104,3,97,11,100,0,4,51,51,51,97,100,0,3,117,115,101>>).
    {11,’333a’,use}
    返回二進(jìn)制數(shù)據(jù)字節(jié)長度
    16> size(<<1,2,3,4>>).
    4
    3.比特語法
    比特語法:一種模式匹配語法,用于二進(jìn)制數(shù)據(jù)中的比特進(jìn)行封包和解包工作。
    比特語法是模式匹配的一種擴(kuò)展。編寫底層代碼時,常會需要對比特級別的二進(jìn)制數(shù)據(jù)進(jìn)行封包解包,會體現(xiàn)比特語法的便捷,比特語法針對協(xié)議編程而設(shè)計(erlang的看家本領(lǐng) 哇塞)。
    16bit色彩的封包解包

    19> Red = 2.
    2
    20> Green = 54.
    54
    21> Blue = 20.
    20
    22> Men = <<Red:5,Green:6,Blue:5>>.
    <<22,212>>
    23> Mem = <<Red:5,Green:5,Blue:5>>.
    <<21,84:7>>
    24> <<R1:5,G1:6,B1:5>> = Men.
    <<22,212>>
    25> R1.
    2
    27> G1.
    54
    28> B1.
    20

    可以看到是用:進(jìn)行匹配,冒號前是數(shù)據(jù),后是所占的比特數(shù)。

    比特語法表達(dá)式

    嗯,這里講比特語法格式:

    比特語法的形式:<<>>或者<<E1,E2,E3,E4,…,En>>。Ei有四種形式:

    Ei = Value | Value:Size | Value/TypeSpecifierList | Value:Size/TypeSpecifierList

    二進(jìn)制數(shù)據(jù)中總比特數(shù)恰好被8整除(二進(jìn)制數(shù)據(jù)中每個字節(jié)都是8bit)。Value必須是一個綁定變量、文本串或者一個返回值的整數(shù)。浮點數(shù)、二進(jìn)制數(shù)據(jù)的表達(dá)式。Size必須為一個整型或者整型綁定變量,不能是自由變量。整型默認(rèn)Size為8,浮點型為64,二進(jìn)制則為本身長度。SpecifierList決定字節(jié)序,取值為:

    @type End = big| little |native

    書上給出一個例子來了解這三種排序和默認(rèn)排序,不同機(jī)器可能不同。

    37> {<<16#12345678:32/big>>,<<16#12345678:32/little>>,<<16#12345678:32/native>>,<<16#12345678:32>>}.
    {<<18,52,86,120>>,
    <<120,86,52,18>>,
    <<120,86,52,18>>,
    <<18,52,86,120>>}

    4.使用總結(jié)

    塊表達(dá)式:

    begin
    Expr1,
    ….
    Exprn
    end

    塊得值就是快中最后一個表達(dá)式的值,用于當(dāng)代碼某處只允許使用單個表達(dá)式而你要用一串表達(dá)式時。

    注釋:

    只有行注釋%,沒有塊注釋。

    列表操作符++ ——:對列表進(jìn)行添加和刪除的中綴操作符。

    比較表達(dá)式:

    所有類型都定義了大小比較順序:

    number<atom<reference<fun<port<pid<tuple<list<binary

    作用:可以對存儲了任何類型的列表進(jìn)行排序,并根據(jù)比較順序,編寫高效的數(shù)據(jù)訪問代碼。

    出了=:=,=/=外,其他都遵循下面規(guī)則:

    如果一個比較參數(shù)為整數(shù),另一個浮點數(shù), 整數(shù)在比較前需要轉(zhuǎn)換成浮點數(shù)。

    如果兩個比較參數(shù)都是整數(shù)或者浮點數(shù),直接比較。。。

    ==只適用于浮點數(shù)和整數(shù)的比較。最好都用=:=。

    ?

    下劃線變量:

    如果一個變量在一個字句中只被使用一次,編譯器會提出警告。但以下劃線開始,那么編譯器不會產(chǎn)生警告信息。

    命名不準(zhǔn)備使用的變量,增加可讀性。方便調(diào)試。

  • 轉(zhuǎn)載于:https://www.cnblogs.com/fvsfvs123/p/4241194.html

    總結(jié)

    以上是生活随笔為你收集整理的Erlang 位串和二进制数据的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。