Dns 二进制数据的Erlang错误

Dns 二进制数据的Erlang错误,dns,binary,erlang,Dns,Binary,Erlang,我刚开始在Erlang上使用我的路径,我面临一个无法解决的问题: 我写了一个metod,将一个域表示为二进制字符串,即按照DNS协议的要求将其转换为域格式,因此: 在下面的代码中(我以不同的方式多次重写): 我以这种方式重写了该方法,但仍然不走运: **注意:我能够修复下面的代码,问题是如果您有一个二进制块,并且希望在另一个二进制字符串中使用它,那么必须在其上指定/binary:这对我来说并不明显 即:考虑这个小代码SNIP: ** TT=, SS=%% 如果字节大小(Bin)>0-> Res=

我刚开始在Erlang上使用我的路径,我面临一个无法解决的问题:

我写了一个metod,将一个域表示为二进制字符串,即按照DNS协议的要求将其转换为域格式,因此:

在下面的代码中(我以不同的方式多次重写):

我以这种方式重写了该方法,但仍然不走运:

**注意:我能够修复下面的代码,问题是如果您有一个二进制块,并且希望在另一个二进制字符串中使用它,那么必须在其上指定/binary:这对我来说并不明显

即:考虑这个小代码SNIP:

**

TT=, SS=%% 如果字节大小(Bin)>0-> Res=二进制:拆分(Bin,), 如果长度(Res)>1-> [Chunk |[RestList]]=Res, ChunkSize=字节大小(块), Rest=域字节(RestList), ; 正确-> [Chunk]=Res, ChunkSize=字节大小(块), 结束 结束。
MdP

我对Erlang有点生疏,但我认为您的问题在于
RestList
是来自
binary:split
输出的块数组

因此,当您递归地将它扔回
domainbyte
时,它的格式是错误的

另外-不要忘记表示根标签的终止NUL字节

FWIW,这是我的工作版本:

label([]) ->
    << 0 >>;

label([H|T]) ->
    D = label(H),
    P = label(T),
    << D/binary, P/binary>>;

label(A) ->
    L = byte_size(A),
    << <<L>>/binary, A/binary>>.

domainbyte(A) ->
    Res = binary:split(A, <<".">>, [global, trim]),
    label(Res).
标签([])->
>;
标签([H|T])->
D=标签(H),
P=标签(T),
>;
标签(A)->
L=字节大小(A),
>.
域字节(A)->
Res=二进制:拆分(A,[全局,修剪],
标签(Res)。

它正确地添加一个尾随NUL字节,并修剪任何额外的尾随点。

二进制文件的concat应该这样写:

<< <<ChunkSize>>/binary, Chunk/binary, Rest/binary>>
% and
<< <<ChunkSize>>/binary, Chunk/binary>>
>
%及
>

我认为最简单的解决方案是使用二进制理解定义函数:

domainbyte(Bin) ->
    Chunks = binary:split(Bin, <<".">>, [global]),      %A list of all the chunks
    << <<byte_size(C),C/binary>> || C <- Chunks >>.     %Build output binary
这与您的代码基本相同,但我们使用模式匹配来选择子句,而不仅仅是分离已知结构。模式匹配是控制的基本方法,不仅在这里的
案例中,而且在函数和
接收中也是如此。这导致
如果
使用非常少


我现在已经受够了。

请不要在代码中的注释中隐藏您的问题。
的输出不应该是
?Thx@rvirding,是的,这是一种类型,我更正了原始帖子。@user1750572是的,您是对的,但由于您所写的内容,当前的代码仍然会崩溃。您好,Thx回复,但正如您在代码中所看到的,我已经考虑过了:正如您所看到的,我考虑过它:[Chunk | RestList]]=Res和thx,用于NUL字节建议……您确定关于
RestList
的附加
[]
集吗?如果没有
global
选项,
RestList
应该只是剩余的父域标签。我正在尝试复制这个,但是我安装的Erlang没有
二进制
模块。hi@Alnitak,是的,它是可以的,在这个源代码中,问题与第6行二进制数据上使用的长度方法有关:if length(RestList)>0。我用另一个棘手的问题修改了如下代码:(
domainbyte(Bin)->if byte_size(Bin)>0->Res=binary:split(Bin,),if length(Res)>1->[Chunk |[RestList]=Res,ChunkSize=byte_size(Chunk),Rest=domainbyte(RestList),;true->[Chunk]=Res,ChunkSize=byte_size(Chunk),end end.
您不应该让
label/1
函数同时在块列表和每个块上工作。尽管它允许您拥有二进制文件和列表的嵌套列表。Thx很多,正如前面所说,我只是一个erlang新手,我完全错过了压缩功能……无论如何,我的第二个实现呢ion?虽然不好,但对我来说似乎是正确的,那么,为什么我会出错呢?我正在努力学习,这种错误令人沮丧……thx。@user1750572理解,列表和二进制,有点深奥,但在某些情况下,它们可以导致非常简洁的代码。@user1750572只是在编写函数的另一种方式上添加了一点。thx@h阿尔费尔夫,我刚想出来…:DThx。如果我的回答有帮助,如果你接受我的回答,我将不胜感激。
label([]) ->
    << 0 >>;

label([H|T]) ->
    D = label(H),
    P = label(T),
    << D/binary, P/binary>>;

label(A) ->
    L = byte_size(A),
    << <<L>>/binary, A/binary>>.

domainbyte(A) ->
    Res = binary:split(A, <<".">>, [global, trim]),
    label(Res).
<< <<ChunkSize>>/binary, Chunk/binary, Rest/binary>>
% and
<< <<ChunkSize>>/binary, Chunk/binary>>
domainbyte(Bin) ->
    Chunks = binary:split(Bin, <<".">>, [global]),      %A list of all the chunks
    << <<byte_size(C),C/binary>> || C <- Chunks >>.     %Build output binary
domainbyte(Bin) ->
    case binary:split(Bin, <<".">>) of
        [Chunk,Rest] ->                       %There was a '.'
            RestBin = domainbyte(Rest),
            Size = byte_size(Chunk),
            <<Size,Chunk/binary,RestBin/binary>>;
        [Chunk] ->                            %This was the last chunk
            Size = byte_size(Chunk),
            <<Size,Chunk/binary,0>>           %Add terminating 0
end.