编码

Erlang 字符串处理的一点小坑

by Cheng, 2024-09-26


偶然间发现了 echo.opera.com 可以打印出请求头,觉得挺好玩的,于是想自己写一个。

在用 Rust 实现了 echo_rs 之后,萌生了用 Erlang 再写一遍的念头,正好用来练习 gen_tcp

按照自己想法写完之后,发现在展示 16 进制原始请求数据的时候,布局都是乱的。

image.png

通过调试之后发现问题出现在了 string:slice 函数上边。这里的处理方式是,将请求袁术数据按照 0x10 的长度进行划分,首选转换成 16 进制的数据,再解析成 ASCII 数据。但是 string:slice 并没有严格按照输入的长度进行划分。

-define(ELEMENT_PER_LINE, 16).

image 2.png

既然 string: slice 没法按照要求,那么能想到的解决方案就是按照二进制处理这些数据,Erlang 天然对二进制处理友好。那么对应的处理方案是先根据二进制划分数据,然后根据划分的数据进行处理。

-spec slice_binary(
    binary(), 
    non_neg_integer(), 
    non_neg_integer()
) -> {ok, binary()}.
slice_binary(Bin, Start, Len) ->
    case Len > byte_size(Bin) - Start of
        true ->
            <<_:Start/binary, Rest/binary>> = Bin,
            {ok, Rest};
        false ->
            <<_:Start/binary, Rest/binary>> = Bin,
            <<Slice:Len/binary, _/binary>> = Rest,
            {ok, Slice}
    end.

这样就能保证获取的数据是想要的长度了。

image 3.png

可以通过 echo 获取到项目的源代码,可以通过 🔗此链接🔗 访问部署的服务。

Erlang

作者: Cheng

2025 © typecho & elise & Cheng