· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.ZEN —› Вопрос по РНР

Посл.отвђт Сообщенiе


Дата: Июн 25, 2004 15:15:35

Товарищи, пишу программу на РНР и возникла проблема, в вычислениях с побитовыми операциями получаю результат отличный от того, который хотелось бы. Программу пишу не с нуля, а переписываю ее с Перла(есть также реализация на Дельфи). Вот в чем собственно проблема, есть такая строка:
 
$s=((($s-$k)-$l)+$SomeData1) xor ($l >> 0x0D);

Здесь переменные имеют следущие значения:
 
$s = 1868983913
$k = 313254387
$SomeData1 = 2654435769
$l = 358929616


В результате после выполнения этого действия в переменную $s записывается значение 3851235679(исполняется под Винд2000). В то время как реализация этого же куска программы в Перле(ФриБСД) и в Дельфи6 дает: 3851262585. При этом и левая скобка, и правая вычисляются правильно, а вот после операции побитового логического отрицания все портится. В чем может быть проблема? Таких мест в программе несколько и после такого "збоя" программа работает уже не так как нужно.
А есхи вместо ХОR поставить ^, то ответ: -443704711. Это тоже "не правильно".

Если все плохо, то может быть есть идеи как можно это обойти?

Как не трудно было заметить, блок с хором не выполняется вообще! Почему? Что ему мешает? Народ, хееелппп!!!


Дата: Июн 25, 2004 18:00:33

<?
$s = 1868983913; // 6F666E69
$k = 313254387; // 12ABE1F3
$SomeData1 = 2654435769; // 9E3779B9
$l = 358929616; // 1564D4D0
$s=($s-$k-$l+$SomeData1) ^ ($l >> 0x0D);
printf("s = %u\n",$s);
?>
Так хорошо? :)


Дата: Июн 25, 2004 18:23:33

Спасибо :)


Дата: Июн 25, 2004 19:05:20

А в чем заморочка. Это показалось правильно, а вот дальше аналогичная трабла.
Строка вида:
$l=(($k >> 0x0D) ^ (($l-$k)-$s));

Дает опять неверный результат. Или там все правильно, а я просто неправильно его вывожу? Делаю так же как и в первом случае.


Дата: Июн 25, 2004 19:47:20

Tristania
может лучше в HEX смотреть дабы избежать таких недоразумений?

т.е.
printf("l = %08X\n",$l);


Дата: Июн 26, 2004 00:35:00

Может, потому что ПХП не умеет 32bit UNSIGNED int ?
.. только через извращения со строками например ..


Дата: Июн 26, 2004 07:58:51

Это показалось правильно, а вот дальше аналогичная трабла.
Трабла, imho, заключается в том, что ты пытаешься работать с большими числами (>0x07FFFFFFF) в ПХП, используя тип int. Этот тип задан там как "знаковое 32-битное"... А ты видимо пытаешься сделать из него "беззнаковое 32-битное" или даже "знаковое 64-битное". В общем, rtfm:
http://ru.php.net/manual/ru/language.types.integer.php
и возможно
http://ru.php.net/manual/ru/ref.gmp.php

ЗЫ Недавно для развлечения подрубил в ПХП джаву, есть там такая возможность. Вот эту возможность тоже можно использовать... Ну, к примеру... :)


Дата: Июн 28, 2004 10:57:27

Давеча, как настоящий хакер, воин дзена, спозаранку встав на лыжи, надев свой боевой противогаз и стоя в гамаке, я реализовал функциональность беззнакового 32-bit int на ПХП.
ПХП'шный знаковый 32-bit int используется как контейнер.
<?
// unsigned addition
function add32($a,$b) {
$of = 0;
$c = 0;
for($i=0; $i<32; $i++) {
$ii = 1<<$i;
$aa = (($a & $ii) >> $i) & 1;
$bb = (($b & $ii) >> $i) & 1;
$ax = $aa + $bb + $of; // [0,3]
$of = ($ax > 1) ? 1 : 0; // overflow
$c |= ($ax & 1) << $i;
}
return $c;
}
// unsigned subtraction
function sub32($a,$b) {
$bb = add32(~$b,1); // get "additional code"
return add32($a,$bb);
}
// unsigned right shift
function shr32($a,$b) {
for($i=0; $i < (32-$b); $i++) {
$ax |= 1<<$i;
}
return (($a >> $b) & $ax);
}
?>

Реализовано три операции: сложение, вычитание и беззнаковый правый сдвиг. Соответственно, вычисляемые выражения приобретают следующий вид:
<?

$s = 1868983913; // 6F666E69
$k = 313254387; // 12ABE1F3
$SomeData1 = 2654435769; // 9E3779B9
$l = 358929616; // 1564D4D0

//$s=($s-$k-$l+$SomeData1) ^ ($l >> 0x0D);
$s = add32(sub32(sub32($s,$k),$l),$SomeData1) ^ shr32($l,0x0D);
printf("s = %u\n--- 3851262585\n",$s);

//$l=(($k >> 0x0D) ^ (($l-$k)-$s));
$l = shr32($k,0x0D) ^ sub32(sub32($l,$k),$s);
printf("l = %u\n",$l);

// l = 489409851

?>
Правильно ли вычислен последний $l ?

В данной реализации не учитывается переполнение за 32 бита. Но, в принципе, функциональность при таком подходе можно расширить хоть до 1024 битовой арифметики :))


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.081