1

%Question
私が2進数を持っているとしましょう:
1011011101111011111
各桁は1ビットです。

それを次のように変換できるようにしたいと思います:
[1、11、111、1111、11111]

...そして最終的に:
[1、2、3、4、5]

%試し
たことbinary:splitを試しましたが、データは常にビットのチャンクでエンコードされます。生データを処理したいだけです(可能な場合)。

達成しようとして
いることルーティングプロトコルのヘッダーを設計しています。パケットにすでにアクセスしたアドレスのリストをヘッダーに含める必要があります。ヘッダー自体にゼロで区切られた連続するヘッダーで構成されるヘッダーを指定すれば、ヘッダーの全長に制限を設ける必要はないと考えました。ヘッダーのヘッダーは、2つの連続するゼロによってヘッダー自体から分離されます。したがって、
<< "Hello World">>というペイロードが
あり、データがalice、bob、carlによってアクセスされた場合、ヘッダーは次のようになります。
<<"alicebobcarl">>
ヘッダーのヘッダーは次のようになります。
(8 * 5 1)0(8 * 3 1)0(8 * 4 1)00
ヘッダーに8ビットエンコーディングを使用していると仮定します。

次に、実際のパケットは次のようになります。
(8 * 5のもの)0(8 * 3のもの)0(8 * 4のもの)00 << "alicebobcarl">> << "Hello World">>

ヘッダーを解読するには、最初に00の最初のインスタンスを見つけ、その00より前のすべてを各0で分割します。次に、結果のリストを、パケットが移動した各アドレスのビット数を含むリストに変換します。その後、最終的にヘッダーからアドレスを読み取り、ペイロードを取得できます。

4

3 に答える 3

1

バイナリを文字列に変換できますか?

できるとしたら、次のようにします。

B = "1011011101111011111",
S = string:tokens(B, "0"),
R = lists:map(fun(E)->length(E) end, S).

しかし、これは効率的ではありません。良い答えを期待してください。

于 2012-10-03T00:51:18.380 に答える
1

resqueへのビット文字列の理解:

1> Inp = <<1:1,0:1,3:2,0:1,7:3>>.
<<"À">>
2> [ size(B) || B <- binary:split(<< <<I>> || <<I:1>> <= Inp >>, <<0>>, [global]) ].
[1,2,3]
于 2012-10-03T07:48:16.467 に答える
0

ヘッダーを解析する方法は次のとおりです。

-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ビットが必要です。

  • しきい値(最大値の数値)を定義できない場合:可変長コーディングを使用します。たとえば、エリアスガンマコーディングまたは指数ゴロンコーディング

于 2012-10-03T06:42:32.657 に答える