Определение PR на PHP (fix)

D
На сайте с 20.12.2006
Offline
6
829

В сети можно найти php-скрипт определения значения PR для сайта.

На 64-битных системах он неверно рассчитывает контрольную сумму,

передаваемую в запросе, - Google не отдает значение PR.

Мое решение этой проблемы заключается в моделировании работы

проблемных функций в 32-битном пространстве.

Необходимо:

1) объявить константу:


define('BITS_AMOUNT', 32);

2) добавить функции:


function get_bits_amount($num)
{
$num = bindec($num);

$BitsAmount = 0;
if ($num <= pow(2, 8))
{
$BitsAmount = 8;
}
elseif ($num <= pow(2, 16))
{
$BitsAmount = 16;
}
elseif ($num <= pow(2, 32))
{
$BitsAmount = 32;
}
else
{
$BitsAmount = BITS_AMOUNT;
}

return $BitsAmount;
}

function bin_change_sign($num)
{
$Result = '';
$BitsAmount = get_bits_amount($num);

// дополнение
if (strlen($num) < $BitsAmount)
{
$num = str_pad($num, $BitsAmount, '0', STR_PAD_LEFT);
}

// инверсия
for ($i = 0; $i < strlen($num); ++$i)
{
$Result .= intval(!$num[$i]);
}

// + 1
$Result = decbin(bindec($Result) + 1);

if (strlen($Result) < $BitsAmount)
{
$Result = str_pad($Result, $BitsAmount, '0', STR_PAD_LEFT);
}

return $Result;
}

function bcnum_to_bin($num)
{
$Result = '';
$Rest = strval(0);

$Num = $num;
while ($Num)
{
$Res = bcdiv($Num, 2, 0);
$Rest = bcsub($Num, bcmul($Res, 2));

$Result .= $Rest;
$Num = $Res;
}

return strrev($Result);
}

function bcnum_xor($a, $b)
{
$Result = '';

$MaxLen = BITS_AMOUNT;

$A = str_pad(strrev($a), $MaxLen, '0');
$B = str_pad(strrev($b), $MaxLen, '0');

for ($i = 0; $i < $MaxLen; ++$i)
{
$Result .= intval($A[$i]) ^ intval($B[$i]);
}
return substr(strrev($Result), -BITS_AMOUNT);
}

function dz_xor($a, $b)
{
if ($a < 0)
{
$A = substr(strval($a), 1);
$A = bcnum_to_bin($A);
$A = bin_change_sign($A);
}
else
{
$A = strval($a);
$A = bcnum_to_bin($A);
}

if ($b < 0)
{
$B = substr(strval($b), 1);
$B = bcnum_to_bin($B);
$B = bin_change_sign($B);
}
else
{
$B = strval($b);
$B = bcnum_to_bin($B);
}

$AXorB = bcnum_xor($A, $B);

$Sign = 1;
if ($AXorB[0] == '1')
{
$Sign = -1;
$AXorB = bin_change_sign($AXorB);
}

$AXorB = bindec($AXorB);

return $Sign * $AXorB;
}

3) изменить тело функции mix():


function mix($a, $b, $c)
{
$a -= $b; $a -= $c; $a = dz_xor($a, zeroFill($c,13));
$b -= $c; $b -= $a; $b = dz_xor($b, ($a<<8));
$c -= $a; $c -= $b; $c = dz_xor($c, (zeroFill($b,13)));
$a -= $b; $a -= $c; $a = dz_xor($a, (zeroFill($c,12)));
$b -= $c; $b -= $a; $b = dz_xor($b, ($a<<16));
$c -= $a; $c -= $b; $c = dz_xor($c, (zeroFill($b,5)));
$a -= $b; $a -= $c; $a = dz_xor($a, (zeroFill($c,3)));
$b -= $c; $b -= $a; $b = dz_xor($b, ($a<<10));
$c -= $a; $c -= $b; $c = dz_xor($c, (zeroFill($b,15)));

return array($a,$b,$c);
}

P.S. Должна быть включена поддержка библиотеки BCMath.

P.S.S. Другой вариант решения можно посмотреть здесь:

http://www.master-x.com/forum/topics/70726/

Новая игра - РПГ! (http://www.igra3k.ru/vip/?posol=24431)

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий