Как преобразовать битовый хэш информации о торренте из базы 32 в базу 16

У меня есть информационный хэш Base32. например IXE2K3JMCPUZWTW3YQZZOIB5XD6KZIEQ, и мне нужно преобразовать его в base16.

Как я могу сделать это с помощью PHP?

Мой код выглядит так:

$hash32=strtolower($hash32);
echo $hash32; // shows - IXE2K3JMCPUZWTW3YQZZOIB5XD6KZIEQ
$hash32=sha1($hash32);
$hash16=base_convert($hash32, 32, 16);
echo "</br>";
echo $hash16 // shows - 3ee5e7325a282c56fe2011125e0492f6ffbcd467

В моем коде хэш информации на основе 16 недействителен.

Действительный информационный хеш: 45C9A56D2C13E99B4EDBC43397203DB8FCACA090

Как я могу получить действительный информационный хэш?

Спасибо


person miyuru    schedule 27.07.2012    source источник
comment
что вы подразумеваете под действительным информационным хешем?   -  person varuog    schedule 27.07.2012
comment
Bittorrent info_hash — это хэш sha1, а не base32. Вы уверены, что делаете правильное преобразование?   -  person Timur    schedule 27.07.2012


Ответы (1)


Я даю вам ответ с добровольным опусканием gmp_strval(gmp_init(strtoupper($hash32), 32), 16);, который только работает с GMP установлен на вашем сервере.

function convBase($numberInput, $fromBaseInput, $toBaseInput)
{
    if ($fromBaseInput==$toBaseInput) return $numberInput;
    $fromBase = str_split($fromBaseInput,1);
    $toBase = str_split($toBaseInput,1);
    $number = str_split($numberInput,1);
    $fromLen=strlen($fromBaseInput);
    $toLen=strlen($toBaseInput);
    $numberLen=strlen($numberInput);
    $retval='';
    if ($toBaseInput == '0123456789')
    {
        $retval=0;
        for ($i = 1;$i <= $numberLen; $i++)
            $retval = bcadd($retval, bcmul(array_search($number[$i-1], $fromBase),bcpow($fromLen,$numberLen-$i)));
        return $retval;
    }
    if ($fromBaseInput != '0123456789')
        $base10=convBase($numberInput, $fromBaseInput, '0123456789');
    else
        $base10 = $numberInput;
    if ($base10<strlen($toBaseInput))
        return $toBase[$base10];
    while($base10 != '0')
    {
        $retval = $toBase[bcmod($base10,$toLen)].$retval;
        $base10 = bcdiv($base10,$toLen,0);
    }
    return $retval;
}

Эта функция, найденная здесь, "преобразует произвольно большое число из любого основания в любое основание". Вам нужно всего лишь преобразовать базовое число 32 в базовое число 16, поэтому:

алфавит с основанием 32: ABCDEFGHIJKLMNOPQRSTUVWXYZ234567

$hash32='IXE2K3JMCPUZWTW3YQZZOIB5XD6KZIEQ';
$hash16=convBase($hash32, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', '0123456789ABCDEF');
//$hash16='45C9A56D2C13E99B4EDBC43397203DB8FCACA090'

Проблема заключалась в том, что base_convert неправильно обрабатывал большие числа.

person Romain    schedule 27.07.2012