Kilka lat temu mój webhost zmienił się z 32-bitowego na 64-bitowy, a krytyczny skrypt PHP przestał działać. Było to spowodowane zmianą operacji < < i >> (przesunięcie bitowe). Udało mi się rozwiązać mój problem, zastępując rotateleft i rotateright rutyny z rotateleft32 i rotateright32 tak:Konwersja złożonych funkcji PHP do pracy z 64-bitowymi kodami
function rotateleft($value, $numleft) {
return (($value << $numleft) | ($value >> (32-$numleft)));
}
function rotateleft32($value, $numleft) {
return ((($value << $numleft) | ($value >> (32-$numleft))) & 0xFFFFFFFF);
}
function rotateright($value, $numright) {
return (($value >> $numright) | ($value << (32-$numright)));
}
function rotateright32($value, $numright) {
return ((($value >> $numright) | ($value << (32-$numright))) & 0xFFFFFFFF);
}
Mam teraz natknąć nowego zestawu kodu, który wydaje się być dokładnie taki sam problem, ale jest bardziej skomplikowane:
function ECC_RotateLeft($a)
{
$copya = makecopy($a);
$bit = ($copya->e[0] & ECC_UPRBIT) ? 1 : 0;
/* looped
for ($i = 0; $i < ECC_MAXLONG - 1; $i++)
$copya->e[$i] = ($copya->e[$i] << 1) | (($copya->e[$i + 1] & ECC_MSB) ? 1 : 0);
$copya->e[0] &= ECC_UPRMASK;
looped */
/* unlooped */
// These lines are optimized for ECC_MAXLONG==4 only!
$bit = ($copya->e[0] & ECC_UPRBIT) ? 1 : 0;
$copya->e[0] = (($copya->e[0] << 1) & ECC_UPRMASK) | (($copya->e[1] & ECC_MSB) ? 1 : 0);
$copya->e[1] = ($copya->e[1] << 1) | (($copya->e[2] & ECC_MSB) ? 1 : 0);
$copya->e[2] = ($copya->e[2] << 1) | (($copya->e[3] & ECC_MSB) ? 1 : 0);
/* unlooped */
$copya->e[3] = ($copya->e[3] << 1) | $bit;
return $copya;
}
function ECC_RotateRight($a)
{
$copya = makecopy($a);
$bit = ($copya->e[ECC_NUMWORD] & 1) ? ECC_UPRBIT : 0;
/* looped
for ($i = ECC_MAXLONG - 1; $i > 0; $i--)
$copya->e[$i] = (($copya->e[$i] >> 1) & 0x7FFFFFFF) | (($copya->e[$i - 1] & 1) ? ECC_MSB : 0);
looped */
/* unlooped */
// Thes lines are optimized for ECC_MAXLONG==4 only!
$copya->e[3] = (($copya->e[3] >> 1) & 0x7FFFFFFF) | (($copya->e[2] & 1) ? ECC_MSB : 0);
$copya->e[2] = (($copya->e[2] >> 1) & 0x7FFFFFFF) | (($copya->e[1] & 1) ? ECC_MSB : 0);
$copya->e[1] = (($copya->e[1] >> 1) & 0x7FFFFFFF) | (($copya->e[0] & 1) ? ECC_MSB : 0);
/* unlooped */
$copya->e[0] = (($copya->e[0] >> 1) & 0x7FFFFFFF) | $bit;
return $copya;
}
mam trzy problemy, próbując naprawić sobie:
- to nie jest mój kod, więc nie jestem obeznany z tym, co próbuje zrobić.
- Nie mam już 32-bitowego serwera do przetestowania go przed
- Jestem odpowiedni, ale nie jestem ekspertem od PHP.
Chciałbym wiedzieć, czy ktoś widzi prostą poprawkę, aby ten kod działał na 64-bitowym serwerze i daje taki sam wynik, jaki miałby na serwerze 32-bitowym.
Jeśli nie, jak poleciłbym debugowanie, biorąc pod uwagę, że nie mam 32-bitowego wyniku do porównania?
Oto dyskusja dotycząca tego problemu i próba uzyskania dewelopera to naprawić: How to get the outdated 32bit keymaker.php Script Working on 64 bit
Powinieneś skonfigurować 32-bitową wersję PHP, prawdopodobnie przez uruchomienie 32-bitowej maszyny wirtualnej. –
Ponadto, jeśli nie jesteś w stanie wykonać porównania bezpośredniego, skąd wiesz, że to powyższy kod jest problemem? –
@OliCharlesworth: To wyedukowane przypuszczenie, oparte na poprawce, której potrzebowałem pierwotnie i na pokrewnym pytaniu Stackoverflow, które wtedy zadałem: http://stackoverflow.com/questions/397738/32-to-64-bit-gotchas-in -php – lkessler