%问题
说我有一个二进制数:
1011011101111011111个
每个数字都是一位。
我希望能够将其转化为:
[1,11,111,1111,11111]
...并最终进入:
[1,2,3,4,5]
%我尝试了什么 我尝试二进制:拆分,但数据总是以比特块编码。我只想处理原始数据(如果可能的话。)
%我想要实现的目标
我正在设计路由协议的标头。我希望标头包含数据包已经访问过的地址列表。我认为如果我给标题本身一个由连续的由零分隔的标题,我就不必对标题的总长度施加任何限制。标题的标题将与标题本身分开两个连续的零。所以如果我有一个有效载荷说:
<<“Hello World”>>
并且alice,bob和carl访问了数据,然后标题为:
<< “alicebobcarl” >>
标题的标题是:
(8 * 5个)0(8 * 3个)0(8 * 4个)00
假设我们对标头使用了一些8位编码。
然后实际的数据包会显示:
(8 * 5个)0(8 * 3个)0(8 * 4个)00<“alicebobcarl”>> <<“Hello World”>>
要解密标题,我首先找到00的第一个实例,然后在每个0之前将所有内容分成00.然后我将结果列表转换为一个列表,其中包含数据包已经遍历的每个地址中的位数至。然后我终于可以从标题中读取地址并检索有效负载。
答案 0 :(得分:1)
你能将二进制转换为字符串吗?
假设您可以,然后执行以下操作:
B = "1011011101111011111",
S = string:tokens(B, "0"),
R = lists:map(fun(E)->length(E) end, S).
但这并不高效。期待很好的答案。
答案 1 :(得分:1)
Bitstring comprehensions到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]
答案 2 :(得分: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]).
让我们在shell中测试它。假设这样的标题'10110111'(必须解析为[1,2,3])+分隔符'00'+某些正文&lt;&lt; 12345:64&gt;&gt;:
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'+&lt;&lt; 12345:64&gt;&gt;
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>>}
即使标头为空(消息以两个连续的零位开始) - 函数解析标题为空列表:
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>>}
<强> P.S。强>
顺便说一下,标题的格式非常多余。如果您想编码大数字,例如,数字1024 - 您需要将其转换为1024个连续的“1”位!
有两种方法可以改善标题的格式:
如果你知道你的任何数字都小于某个阈值数:计算你需要用最大值编码数字的位数,并且用标题符号中的每个数字编码预定长度。例如 - 如果您的所有数字都小于2 ^ 32 - 您需要32位来编码此间隔中的每个数字
如果您无法定义阈值(具有最大值的数字):使用可变长度编码。例如,Elias gamma-coding或Exponential-Golomb coding。