Я пытаюсь обновить PHP 5.2.x до 5.3.2 на моем сервере.Проблема в том, что я опираюсь на неработающую реализацию PHP-функции ezmlm_hash () (ошибка описана здесь: http://bugs.php.net/bug.php?id=47969).
Моей первой мыслью было переписать сломанную версию нативной функции PHP(который написан на C) сам на PHP и использую его в своем коде, вместо изменения исходного кода PHP и необходимости компилировать PHP из исходного кода.
Вот версия кода на C:
PHP_FUNCTION(ezmlm_hash)
{
char *str = NULL;
unsigned int h = 5381L;
int j, str_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
&str, &str_len) == FAILURE) {
return;
}
for (j = 0; j < str_len; j++) {
h = (h + (h << 5)) ^ (unsigned long) (unsigned char) tolower(str[j]);
}
h = (h % 53);
RETURN_LONG((int) h);
}
вот что я написал в PHP:
function ezmlm_hash_mine($email_address){
$h = 5381;
$email_length = strlen($email_address);
for($x=0;$x<$email_length;$x++){
$chr = strtolower($email_address[$x]);
$h = ($h + ($h << 5)) ^ ( ord($chr) );
}
$h = $h % 53;
return $h;
}
Я использую 64-битную машину. Две функции выдают разные результаты:
$email_addresses = array(
'test@example.com',
'mike@example.com',
);
print('<PRE>');
foreach($email_addresses as $email_address){
print(ezmlm_hash($email_address).PHP_EOL);
print(ezmlm_hash_mine($email_address).PHP_EOL.PHP_EOL);
}
output:
23
-52
15
-21
Я знаю, что у меня, возможно, есть проблемы с точностью или типизацией, но я просто не знаю, как это исправить. Любая помощь будет принята с благодарностью!
ОБНОВЛЕНИЕ
Когда я запускаю код на 32-битных машинах, они оба выводят новые исправленные значения:
12
12
45
45
Я думаю, это как-то связано с оператором по модулю... кто-нибудь знает PHP эквивалент оператора C по модулю?% в PHP bПо-разному!
ОБНОВЛЕНИЕ 2
Кажется, что это невозможно с ванильным PHP, так как его арифметика с плавающей запятой не имеет достаточной точности, и странность в,Я должен установить либо BCMath, либо GMP.Спасибо всем за понимание.