Umstellung von 32-Bit auf 64-Bit

Sasser

Erfahrenes Mitglied
Guten Tag!

Bisher habe ich mit meinem 32-Bit Server mit dem folgenden Code erfolgreich einen Pagerank abgefragt. Nun habe ich auf 64-Bit umgestellt und schon funktioniert dieser nicht mehr, d.h. es kommt immer 0 heraus. An was liegt das Problem und wie könnte man es beheben? Ich habe leider schon eine ganze Weile bei Google nach einem funktionsfähigen Script gesucht... Vergebens...

PHP:
define('GOOGLE_MAGIC', 0xE6359A60);

// Use this class if your server is having problems with bitwise operations
class PageRankXor32 extends PageRank {
	function xor32($a, $b) {
		return $this->int32($a) ^ $this->int32($b);
	}
	//return least significant 32 bits
	//works by telling unserialize to create an integer even though we provide a double value
	function int32($x) {
		return unserialize("i:$x;");
		//return intval($x); // This line doesn't work on all servers.
	}
	
	function mix($a,$b,$c) {
		$a -= $b; $a -= $c; $a = $this->xor32($a,$this->zeroFill($c,13));
		$b -= $c; $b -= $a; $b = $this->xor32($b,$a<<8);
		$c -= $a; $c -= $b; $c = $this->xor32($c,$this->zeroFill($b,13));
		$a -= $b; $a -= $c; $a = $this->xor32($a,$this->zeroFill($c,12));
		$b -= $c; $b -= $a; $b = $this->xor32($b,$a<<16);
		$c -= $a; $c -= $b; $c = $this->xor32($c,$this->zeroFill($b,5));
		$a -= $b; $a -= $c; $a = $this->xor32($a,$this->zeroFill($c,3));
		$b -= $c; $b -= $a; $b = $this->xor32($b,$a<<10);
		$c -= $a; $c -= $b; $c = $this->xor32($c,$this->zeroFill($b,15));
		return array($a,$b,$c);
	}
}	

//This class should work on most servers
class PageRank {
	function zeroFill($a, $b){
		$z = hexdec(80000000);
		if ($z & $a){
			$a = ($a>>1);
			$a &= (~$z);
			$a |= 0x40000000;
			$a = ($a>>($b-1));
		}else{
			$a = ($a>>$b);
		}
		return $a;
	}
	
	function mix($a,$b,$c) {
		$a -= $b; $a -= $c; $a ^= ($this->zeroFill($c,13));
		$b -= $c; $b -= $a; $b ^= ($a<<8);
		$c -= $a; $c -= $b; $c ^= ($this->zeroFill($b,13));
		$a -= $b; $a -= $c; $a ^= ($this->zeroFill($c,12));
		$b -= $c; $b -= $a; $b ^= ($a<<16);
		$c -= $a; $c -= $b; $c ^= ($this->zeroFill($b,5));
		$a -= $b; $a -= $c; $a ^= ($this->zeroFill($c,3));
		$b -= $c; $b -= $a; $b ^= ($a<<10);
		$c -= $a; $c -= $b; $c ^= ($this->zeroFill($b,15));
		return array($a,$b,$c);
	}
	
	function GoogleCH($url, $length=null, $init=GOOGLE_MAGIC) {
		if(is_null($length)) {
			$length = sizeof($url);
		}
		$a = $b = 0x9E3779B9;
		$c = $init;
		$k = 0;
		$len = $length;
		while($len >= 12) {
			$a += ($url[$k+0] +($url[$k+1]<<8) +($url[$k+2]<<16) +($url[$k+3]<<24));
			$b += ($url[$k+4] +($url[$k+5]<<8) +($url[$k+6]<<16) +($url[$k+7]<<24));
			$c += ($url[$k+8] +($url[$k+9]<<8) +($url[$k+10]<<16)+($url[$k+11]<<24));
			$mix = $this->mix($a,$b,$c);
			$a = $mix[0]; $b = $mix[1]; $c = $mix[2];
			$k += 12;
			$len -= 12;
		}
		$c += $length;
		switch($len){
			case 11: $c+=($url[$k+10]<<24);
			case 10: $c+=($url[$k+9]<<16);
			case 9 : $c+=($url[$k+8]<<8);
			/* the first byte of c is reserved for the length */
			case 8 : $b+=($url[$k+7]<<24);
			case 7 : $b+=($url[$k+6]<<16);
			case 6 : $b+=($url[$k+5]<<8);
			case 5 : $b+=($url[$k+4]);
			case 4 : $a+=($url[$k+3]<<24);
			case 3 : $a+=($url[$k+2]<<16);
			case 2 : $a+=($url[$k+1]<<8);
			case 1 : $a+=($url[$k+0]);
		}
		$mix = $this->mix($a,$b,$c);
		/* report the result */
		return $mix[2];
	}
	
	//converts a string into an array of integers containing the numeric value of the char
	function strord($string) {
		for($i=0;$i<strlen($string);$i++) {
			$result[$i] = ord($string{$i});
		}
		return $result;
		}

	//returns -1 if no page rank was found
	function getRank($url){
		$ch = "6".$this->GoogleCH($this->strord("info:" . $url));
		
		$pagerank=-1;
		$fp = fsockopen("www.google.com", 80, $errno, $errstr, 30);
		if (!$fp) {
			echo "$errstr ($errno)<br />\n";
		} else {
			$out = "GET /search?client=navclient-auto&ch=" . $ch .  "&features=Rank&q=info:" . $url . " HTTP/1.1\r\n" ;
			$out .= "Host: www.google.com\r\n" ;
			$out .= "Connection: Close\r\n\r\n" ;
			fwrite($fp, $out);
			while (!feof($fp)) {
				$data = fgets($fp, 128);
				$pos = strpos($data, "Rank_");
				if($pos === false){
				}else{
				$pagerank = trim(substr($data, $pos + 9));
				}
			}
			fclose($fp);
		}
		return $pagerank;
	}
}
 
So, nach ca. 30 behobenen Syntaxfehlern, läuft das Script jedenfalls schonmal, allerdings lädt es und lädt und lädt...

PHP:
<?php

function StrToNum($Str, $Check, $Magic)
{
$Int32Unit = 4294967296;
$length = strlen($Str);
for ($i = 0; $i < $length; $i++) {
$Check *= $Magic;
if ($Check >= $Int32Unit) {
$Check = ($Check - $Int32Unit * (int) ($Check / $Int32Unit));
$Check = ($Check < -2147483648)? ($Check + $Int32Unit) : $Check;
}
$Check += ord($Str{$i});
}
return $Check;
}

function HashURL($String)
{
$Check1 = StrToNum($String, 0x1505, 0x21);
$Check2 = StrToNum($String, 0, 0x1003F);
$Check1 >= 2;
$Check1 = (($Check1 > 4) && 0x3FFFFC0 ) | ($Check1 && 0x3F);
$Check1 = (($Check1 > 4) && 0x3FFC00 ) | ($Check1 && 0x3FF);
$Check1 = (($Check1 > 4) && 0x3C000 ) | ($Check1 && 0x3FFF);
$T1 = (((($Check1 && 0x3C0) < 4) | ($Check1 && 0x3C)) <2 ) | ($Check2 && 0xF0F );
$T2 = (((($Check1 && 0xFFFFC000) < 4) | ($Check1 && 0x3C00)) < 0xA) | ($Check2 && 0xF0F0000 );
return ($T1 | $T2);
}

function CheckHash($Hashnum)
{
$CheckByte = 0;
$Flag = 0;
$HashStr = sprintf('%u', $Hashnum) ;
$length = strlen($HashStr);
for ($i = $length - 1; $i >= 0; $i --) {
$Re = $HashStr{$i};
if (1 == ($Flag % 2)) {
$Re += $Re;
$Re = (int)($Re / 10) + ($Re % 10);
}
$CheckByte += $Re;
$Flag ++;
}
$CheckByte %= 10;
if (0 != $CheckByte) {
$CheckByte = 10 - $CheckByte;
if (1 == ($Flag % 2) ) {
if (1 == ($CheckByte % 2)) {
$CheckByte += 9;
}
$CheckByte >= 1;
}
}
return "?".$CheckByte.$HashStr;
}

function getpagerank($url) 
{
$fp = fsockopen("toolbarqueries.google.com", 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />";
} else {
$out = "GET /search?client=navclient-auto&ch=".CheckHash(HashURL($url))."&features=Rank&q=info:".$url."&num=100&filter=0 HTTP/1.1";
$out .= "Host: toolbarqueries.google.com";
$out .= "User-Agent: Mozilla/4.0 (compatible; GoogleToolbar 2.0.114-big; Windows XP 5.1)";
$out .= "Connection: Close";

fwrite($fp, $out);

//$pagerank = substr(fgets($fp, 128), 4);
//echo $pagerank;
while (!feof($fp)) {
$data = fgets($fp, 128);
$pos = strpos($data, "Rank_");
if($pos === false){} else{
$pagerank = substr($data, $pos + 9);
echo $pagerank;
}
}
fclose($fp);
}
}

echo getpagerank('google.de');

?>
 
Zuletzt bearbeitet:
Moin!

PHP:
$out = "GET /search?client=navclient-auto&ch=".CheckHash(HashURL($url))."&features=Rank&q=info:".$url."&num=100&filter=0 HTTP/1.1";
$out .= "Host: toolbarqueries.google.com";
$out .= "User-Agent: Mozilla/4.0 (compatible; GoogleToolbar 2.0.114-big; Windows XP 5.1)";
$out .= "Connection: Close";

Ohne das Skript weiter zu analysieren - wie wär's mit Newline Zeichen? :)


Gruß
Enum
 
Hmm brachte leider auch nix...

Ich nehme mal an, es kursieren sehr viele Scripte im Netz rum, welche angeblich auch auf 64-Bit Systemen laufen soll. Allerdings glaube ich, dass ich mich einfach damit abfinden und warten muss, auch wenn ich riskiere dass dadurch meine User sich verabschieden!? :(
 
Temporär, bis du was neues gefunden hast, kannst du ja ein 32Bit-PHP verwenden. Ich sehe auch grad nicht, wo hier die Probleme liegen sollten. Ein int ist ein int ist ein int. Sollte auf 64Bit-Architekturen eigentlich auch noch 32bit breit sein, das PHP hier sein eigenes Süppchen kocht und long als integer verkauft, finde ich seltsam. Du kannst ja mal die Methode int32() in der Klasse PageRankXor32 aus deinem ersten Post so modifizieren, das sie den intval() statt dem unserialize() verwendet, wobei ich keine Ahnung habe, wie intval intern arbeitet. Möglicherweise bekommst du trotzdem ein 64bit-int zurück.

Außerdem habe ich noch diese Seite gefunden: http://stackoverflow.com/questions/864058/how-to-have-64-bit-integer-on-php

Vielleicht kannst du damit das Äquivalent für 32Bit-Werte bauen.
 
Zurück