Вычисление info_hash из строки запроса UrlEncoded
По сути, я строю небольшой трекер для экспериментальных целей. Я прошел довольно далеко и сейчас работаю над анонсом.
Что я действительно не могу понять, так это то, как я должен декодировать предоставленную строку запроса info_hash.
Исходя из спецификации, это 20-байтовый хеш SHA1 с кодировкой Urlen, который заставил меня написать этот код,
byte[] foo = Encoding.Default.GetBytes(HttpUtility.UrlDecode(infoHash));
string temp = "";
foreach (byte b in foo)
{
temp += b.ToString("X");
}
Что дает 'temp' следующее значение,
5D3F3F3F3F5E3F3F3F153FE4033683F55693468
Первые и последние несколько символов верны. Это необработанный info_hash,
%5d%96%b6%f6%84%5e%ea%da%c5%15%c4%0e%403h%b9Ui4h
И это то, что и uTorrent, и мой собственный трекер дают мне как info_hash при генерации его из торрент-файла,
5D96B6F6845EEADAC515C40E403368B955693468
Что я делаю неправильно?
2 ответа
UrlDecode возвращает строку, но хеш SHA1 не имеет смысла, если интерпретировать его как (ANSI) строку.
Вам необходимо декодировать входную строку непосредственно в байтовый массив, без обращения к строке.
var s = "%5d%96%b6%f6%84%5e%ea%da%c5%15%c4%0e%403h%b9Ui4h";
var ms = new MemoryStream();
for (var i = 0; i < s.Length; i++)
{
if (s[i] == '%')
{
ms.WriteByte(
byte.Parse(s.Substring(i + 1, 2), NumberStyles.AllowHexSpecifier));
i += 2;
}
else if (s[i] < 128)
{
ms.WriteByte((byte)s[i]);
}
}
byte[] infoHash = ms.ToArray();
string temp = BitConverter.ToString(infoHash);
// "5D-96-B6-F6-84-5E-EA-DA-C5-15-C4-0E-40-33-68-B9-55-69-34-68"