ヘッダーを解析する方法は次のとおりです。
-module(bitcnt).
-export([parse_header/1]).
parse_header(Message) ->
parse_header(Message, []).
parse_header(<<0:1, 0:1, Body/bitstring>>, Header) ->
%% stop if found header delimiter - two consecutive zero bits
%% return parsed header and message body
{lists:reverse(Header), Body};
parse_header(<<1:1, Rest/bitstring>>, []) ->
%% handle if first bit is '1'
parse_header(Rest, [1]);
parse_header(<<1:1, Rest/bitstring>>, [H | T]) ->
%% handle consecutive '1' bits of header
parse_header(Rest, [H+1 | T]);
parse_header(<<0:1, Rest/bitstring>>, Header) ->
%% handle delimiters inside header - '0' bit
parse_header(Rest, [0 | Header]).
シェルでテストしてみましょう。このようなヘッダー「10110111」([1,2,3]に解析する必要があります)+区切り文字「00」+本文<< 12345:64 >>:
2> B1 = <<1:1,0:1,1:1,1:1,0:1,1:1,1:1,1:1,0:1,0:1,12345:64>>.
<<183,0,0,0,0,0,0,12,14,1:2>>
3>
3> bitcnt:parse_header(B1).
{[1,2,3],<<0,0,0,0,0,0,48,57>>}
4>
4> <<12345:64>>.
<<0,0,0,0,0,0,48,57>>
別のテスト「11101」([3,1]に解析する必要があります)+ '00' + << 12345:64 >>
5> B2 = <<1:1, 1:1, 1:1, 0:1, 1:1, 0:1, 0:1, 12345:64>>.
<<232,0,0,0,0,0,0,96,57:7>>
6>
6> bitcnt:parse_header(B2).
{[3,1],<<0,0,0,0,0,0,48,57>>}
ヘッダーが空の場合でも(メッセージは2つの連続するゼロビットで始まります)-関数はヘッダーを空のリストに解析します:
7> B3 = <<0:1, 0:1, 12345:64>>.
<<0,0,0,0,0,0,12,14,1:2>>
8>
8> bitcnt:parse_header(B3).
{[],<<0,0,0,0,0,0,48,57>>}
PS
ちなみに、ヘッダーの形式は非常に冗長です。大きな数値、たとえば1024の数値をエンコードする場合は、1024の連続する「1」ビットに変換する必要があります。
ヘッダーの形式を改善するには、次の2つの方法があります。
数値のいずれかがしきい値の数値よりも小さいことがわかっている場合:数値を最大値でエンコードするために必要なビット数を計算し、事前定義された長さのビット文字列を使用してヘッダー内の各数値をエンコードします。たとえば、すべての数値が2 ^ 32未満の場合、この間隔から各数値をエンコードするには32ビットが必要です。
しきい値(最大値の数値)を定義できない場合:可変長コーディングを使用します。たとえば、エリアスガンマコーディングまたは指数ゴロンコーディング。