Erlang:ipv6值到八位字节二进制值

时间:2017-01-31 06:03:18

标签: erlang

我想将HTX中的IPv6值转换为Octet二进制文件。

Ipv6:2001:db8:85a3:8d3:1319:8a2e:370:7348

是否有任何示例格式如何erlang八位字节二进制看起来以及我如何转换它。

提前致谢 普里亚

2 个答案:

答案 0 :(得分:4)

您可以使用函数inet:parse_ipv6_address/1将地址解析为整数:

> {ok, {A,B,C,D,E,F,G,H}} = inet:parse_ipv6_address("2001:db8:85a3:8d3:1319:8a2e:370:7348").
{ok,{8193,3512,34211,2259,4889,35374,880,29512}}

然后,您可以将这些整数组合成一个二进制文件:

> <<A:16, B:16, C:16, D:16, E:16, F:16, G:16, H:16>>.
<<32,1,13,184,133,163,8,211,19,25,138,46,3,112,115,72>>

该结果中显示的每个数字都是一个八位字节。

答案 1 :(得分:0)

你可以使用很多方法如果你想手动完成,我会使用匿名函数给你一个。

% IPv6 addresses are split in 8 parts, each parts 
% are coded in hexadecimal, starting from 0 to ffff.
% In decimal: 0 to 65535.
Ip6Parser = fun % if we match empty bitstring, we return the value
                F(<<>>, Return, Buffer) -> 
                  Convert = erlang:binary_to_integer(Buffer, 16),
                  <<Return/bitstring, Convert:16>>;

                % if we match semi-column (:) char, we switch to
                % another ipv6 part
                F(<<":", Rest/bitstring>>, Return, <<>>) ->
                  F(Rest, <<Return/bitstring, 0:16>>, <<>>);
                F(<<":", Rest/bitstring>>, Return, Buffer) -> 
                  Convert = erlang:binary_to_integer(Buffer, 16),
                  F(Rest, <<Return/bitstring, Convert:16>>, <<>>);

                % currently, we use ascii representation, coded
                % on 8bits. We need to check if this byte is a
                % correct number (see guards)
                F(<<Char:8, Rest/bitstring>>, Return, Buffer) 
                  when Char >= $0 andalso Char =< $9 orelse
                       Char >= $a andalso Char =< $f orelse
                       Char >= $A andalso Char =< $F ->
                    F(Rest, Return, <<Buffer/bitstring, Char>>);

                % if we don't match hexadecimal representation
                % we return an error.
                F(Rest, Return, Buffer) ->
                  {error, badvalue, {Rest, Return, Buffer}}
             end.

我们可以像这样使用这段代码:

Ip6Parser(<<"2001:db8:85a3:8d3:1319:8a2e:370:7348">>, <<>>, <<>>).

并将返回:

<<32,1,13,184,133,163,8,211,19,25,138,46,3,112,115,72>>

可以肯定的是,我们可以检查前16位是否编码良好:

<<First:16, Rest/bitstring>> = 
    Ip6Parser(<<"2001:db8:85a3:8d3:1319:8a2e:370:7348">>, <<>>, <<>>).
First
% return 8193 in decimal

如果要以十六进制检查此值:

erlang:integer_to_list(First, 16).
% will return "2001"

您可以在此处找到有关所有方面的更多信息:

注意:此代码仅适用于Erlang R18和R19。如果你想在较低版本上执行它,你需要创建专用函数,或者为这个lambda函数添加一个参数(引用当前的lambda函数),类似:

Ipv6 = fun (Bitstring, Return, Buffer, Fun)
         when is_function(Fun) ->
            Fun(Bitstring, Return, Buffer, Fun).

玩得开心! ;)