Разобрать бинарный код в Erlang - PullRequest
2 голосов
/ 25 марта 2011

Если у меня есть следующий двоичный файл: <<"GET <a href="http://www.google.com" rel="nofollow">http://www.google.com</a> HTTP/1.1">>, как я могу разделить его так, чтобы я мог получить только хост (http://www.google.com)?

Я начал с чего-то вроде:

get_host(<<$G, Rest/binary>>) -> get_host(Rest);<br> get_host(<<$E, Rest/binary>>) -> get_host(Rest);<br> get_host(<<$T, Rest/binary>>) -> get_host(Rest);

но я не уверен, как дальше отсюда. Я думал о том, чтобы изменить Rest и начать с конца двоичного файла.

Ответы [ 3 ]

10 голосов
/ 25 марта 2011

Кажется, вы пытаетесь реализовать минимальный парсер для HTTP 1.1 . Это одно решение , которое соответствует спецификациям HTTP 1.1 и анализирует первую строку http-запроса. Не зная вашей конкретной ситуации, я бы в большинстве случаев рекомендовал использовать общий синтаксический анализатор HTTP перед упрощенным «разделенным двоичным файлом» или аналогичным.

1> erlang:decode_packet(http,<<"GET http://www.google.com HTTP/1.1\n">>,[]).  
{ok,{http_request,'GET',
              {absoluteURI,http,"www.google.com",undefined,"/"},
              {1,1}},
<<>>}
3 голосов
/ 25 марта 2011

Я бы порекомендовал erlang:decode_packet для этого, но чтобы показать, как это можно сделать, вот пара функций, которая удаляет ведущий "GET ", а затем возвращает все до первого пробела (но вылетает, если нет пространство).

get_host(<<"GET ", Rest/binary>>) ->
    get_host2(Rest, <<>>).

get_host2(<<" ", _/binary>>, Acc) ->
    Acc;
get_host2(<<C, Rest/binary>>, Acc) ->
    get_host2(Rest, <<Acc/binary, C>>).

По сути, я помещаю каждый байт, который не является пробелом, в мой «аккумулятор», и когда я нахожу это место, я возвращаю свой аккумулятор. Это распространенный прием, который чаще всего встречается в списках. (Со списками вы захотите поместить новые элементы в перед списка и полностью изменить список в конце, чтобы избежать превращения алгоритма O (N) в O (N²), но это не нужно для двоичных файлов.)

0 голосов
/ 25 марта 2011

Простой ответ (но, вероятно, не тот, который вы действительно просите)

B = <<"GET http://www.google.com HTTP/1.1">> .
{_,H}=split_binary(B,4). 
split_binary(H,21).
...