2010-11-08 3 views
5

Я пытаюсь найти правильный хэш-код, закодированный в url, для отправки трекеру, чтобы получить список сверстников.Разбор торрент-файла - хэш-информация. (Erlang)

Для тестирования я попытался разобрать торрент в this url.

После открытия файла, вручную вырезать информации словарную часть и SHA1 хэш-это значение я получаю это двоичное значение:

< < 84,124,15,255,155,171,156,168,91,46,204,24,249,116,110, 139,202,167,163,54 >>

Строка ASCII, полученная из последнего двоичного значения, составляет 788f590f28a799cc1009a9b780b649fd6f0a2e91, и это то же значение, упоминаемое на сайте.

Итак, давайте предположим, что все правильно до сих пор (не так ли?).

После кодирования двоичное значение с помощью функции URL-кодирования ниже я получаю Т% 7c% 0f% и далее% 9b% AB% 9c% а8% 5b.% Куб.см% 18% f9tn% 8b% Ca% а7% a36, который даже не близок к правильному значению urlencoded, которое я должен отправить трекеру. (Я получаю сообщение об ошибке, которое не было обнаружено, когда я отправляю это трекеру, плюс, он не соответствует значению, которое я вижу, используя wirehark, который равен x% 8fY% 0f% 28% a7% 99% cc% 10% 09% a9 % b7% 80% b6I% fdo% 0a.% 91).

Функция URL Encoding Я использую:

encode(<<Bin:20/binary-unit:8>>)-> 
    %io:format("~p~n", [binary_to_list(Bin)]), 
    encode(binary_to_list(Bin)); 
encode(List) -> do_encode(List). 

do_encode([])-> []; 
do_encode([H|T]) when H>=$a, H=<$z -> 
    [H| encode(T)]; 
do_encode([H|T]) when H>=$A, H=<$Z -> 
    [H| encode(T)]; 
do_encode([H|T]) when H>=$0, H=<$9 -> 
    [H| encode(T)]; 
do_encode([H|T]) when H==$- -> 
    [H| encode(T)]; 
do_encode([H|T]) when H==$. -> 
    [H|do_encode(T)]; 
do_encode([H|T]) when H==$* -> 
    [H|do_encode(T)]; 
do_encode([H|T]) -> 
    to_hex(H) ++ encode(T). 

hex(N) when N < 10 -> 
    $0+N; 
hex(N) when N >= 10, N < 16 -> 
    $a+(N-10). 
to_hex(N) when N < 256 -> 
    [$%, hex(N div 16), hex(N rem 16)]. 

ли функция выше неправильно? Я как-то новичок, когда дело доходит до обработки необработанных данных. поэтому помощь/идеи очень ценятся! Благодаря!

ответ

1

Обратите внимание, что URL-кодирование уже доступно в erlang (хотя и хорошо скрыто).

1> B = <<84,124,15,255,155,171,156,168,91,46,204,24,249,116,110, 139,202,167,163,54>>. 
<<84,124,15,255,155,171,156,168,91,46,204,24,249,116,110, 
2> L = erlang:binary_to_list(B). 
[84,124,15,255,155,171,156,168,91,46,204,24,249,116,110,139, 
202,167,163,54] 
3> edoc_lib:escape_uri(L). 
"T%7c%f%c3%bf%c2%9b%c2%ab%c2%9c%c2%a8%5b.%c3%8c%18%c3%b9tn%c2%8b%c3%8a%c2%a7%c2%a36" 

Это дает тот же результат, что и ваш.

+0

Я попытался использовать escape_uri(), который дал другой результат от того, который «uTorrent» отправляет трекеру, поэтому я попытался реализовать свою собственную, чтобы узнать, могу ли я получить правильное значение. если это правильная кодировка данного двоичного кода, то как получилось, что значение, отправленное на трекер, отличается? – Smokie

1

Ваша проблема связана не с вашим кодировщиком, а с вашим первоначальным предположением о данных. Строка мы имеем «788f590f28a799cc1009a9b780b649fd6f0a2e91», поэтому мы пишем немного Erlang кода, чтобы преобразовать это в его двоичном представлении в виде списка:

part([]) -> []; 
part([U,L | R]) -> 
    [{list_to_integer([U], 16), 
     list_to_integer([L], 16)} | part(R)]. 

Теперь, задавая в строке дает:

([email protected])16> etorrent_utils:build_encoded_form_rfc1738([U*16+L || {U,L} <- foo:part("788f590f28a799cc1009a9b780b649fd6f0a2e91")]). 
"x%8FY%0F%28%A7%99%CC%10%09%A9%B7%80%B6I%FDo%0A.%91" 

Соответствие ожидаемому. Вы должны убедиться, что ваш ручной сбор данных infohash и его расчет SHA1 работают так, как вы ожидаете, что он будет работать. Потому что ваш двоичный файл SHA1 не соответствует ему.