搜索
首页后端开发php教程Google PR查询接口checksum新算法_php实例

前些日子一篇N久之前的老文忽然成了被阅读的热点,检查之后才发现自己使用那段代码来做pr查询的页面已经不能正常得到URL的Page Rank值了

取而代之的是一大段“In your email, please send us the entire code displayed below”之类的Google terms_of_service错误提示信息。看来是原先的接口已经失效了。

但我装在Firefox工具栏的扩展插件SearchStatus仍然能够正常解析出每个受访页的PR值,找到 SearchStatus 的插件包解开来看源码,果然是使用了不一样的验证码生成算法,在原先的 checksum 生成之后,还需要再进行一次计算,两次演算之后得到的才是正确的ch参数。

于是拿现成的js代码改造一番之后,新的PHP版本的 Google PageRank 查询接口方法就出来了。经过本地测试之后,谁想传到服务器之后又出现了该死的 terms_of_service 错误提示。把checksum的计算过程一步步打出来,发现经过了几次右位移之后本地和服务器上的数字就不一样了。这才想到服务器是64位机,32位系统下位移之后应该被cut掉的bit在那里就活得好好的。加了个 trunkbitForce32bit 方法,对所有算术运算之后的数值进行高位屏蔽,算是搞定了64位系统下的多余位问题。结果拿到32位Linux环境下跑又不兼容了,原因是PHP在进行算术处理出现溢出时,会自动尝试将int转为float。当发生的是负数溢出时,这一操作在Windows下能正确保留精度,但在Linux下就有问题了。

下面这段代码:

$a = -4294967295;
echo dechex($a)."df250b2156c434f3390392d09b1c9563\n";
if ( $a < 0 ) $a += 4294967296;
echo dechex($a)."df250b2156c434f3390392d09b1c9563\n";

第一个echo在Windows下能够正确输出该负数低32位的补码,而在32位Linux机上输出的则是int类型所能表示的最大负数0x80000000了。只有通过取巧的方式给这个溢出的大负数加上一个超出整数范围的大整数来抵消掉溢出的部分,才能复原低32位应该有的样子。

使用这些非常规手段,终于炮制出这个更新版的兼容Linux32/Linux64/Windows的Google PR值查询接口的PHP脚本实现(含完整代码)。


Google本身提供了查询指定的url的PageRank值的接口,知道了这个接口,就可以很容易编写脚本在页面上实现这一功能,而无需再依赖google toolbar才能进行查询。本文提供了一个用PHP实现的pr查询接口。同时修正了大部分版本中存在的 Linux 操作系统及64位操作系统下无法正常生成checksum的问题。


使用很简单,只要在需要的地方

fa7dc1d850e835711a146b717700644c

即可显示出指定url的PageRank的数值。知道了这个数值再在其基础上模拟出Google Toolbar上面的图形化的pr显示也就不是难事了。实际上实现原理说白了也很简单,就是传递特定的查询参数到Google的搜索引擎,然后抓取返回的页面内容。

演示页面请参见 : Google PageRank Query

本文代码素材来源: http://www.php.cn/ ;NewGCH方法实现参考于Firefox的工具栏扩展插件SearchStatus的相关代码实现。

网上还有一个开源的pr状态查询的项目: http://www.php.cn/ , 可以从cvs上直接抓取完整的源代码(cvs用户密码 guest):

cvs -d :pserver:guest@mozdev.org:/cvs login
cvs -d :pserver:guest@mozdev.org:/cvs co pagerankstatus

一个专门提供pr显示接口的网站: http://www.php.cn/

------------------------------------------------------------------

pr.inc.php源文件如下(Updated 2008-05-04 14:29 -- Google修改了checksum的计算算法,需要在原有的GCH方法之后再套一层NewGCH方法来得到正确的checksum,同时引发的php int overflow及64位机器兼容性问题请参照以下源代码的变化部分):

<?php 
// url get method macro. 
define(&#39;G_PR_GET_TYPE_FILE&#39;, 1); // use fopen() function 
define(&#39;G_PR_GET_TYPE_SOCKET&#39;, 2); // use standard fsocketopen function 
// main function to be called 
function getPR($_url,$gettype=G_PR_GET_TYPE_SOCKET){ 
$url = &#39;info:&#39;.$_url; 
$ch = GCH(strord($url)); 
$ch = NewGCH($ch); 
$url=str_replace("_","%5F",&#39;info:&#39;.urlencode($_url)); 
$googlePRUrl = 
"http://toolbarqueries.google.com/search?client=navclient-auto&ch=6" 
.$ch."&ie=UTF-8&oe=UTF-8&features=Rank&q=".$url; 
$pr_str = retrieveURLContent($googlePRUrl,$gettype); 
return substr($pr_str,strrpos($pr_str, ":")+1); 
} 
//unsigned shift right 
function zeroFill($a, $b){ 
$z = hexdec(&#39;8&#39;.implode(&#39;&#39;,array_fill(0,PHP_INT_SIZE*2-1,&#39;0&#39;))); 
if ($z & $a){ 
$a = ($a>>1); 
$a &= (~$z); 
$a |= hexdec(&#39;4&#39;.implode(&#39;&#39;,array_fill(0,PHP_INT_SIZE*2-1,&#39;0&#39;))); 
$a = ($a>>($b-1)); 
} 
else{ 
$a = ($a>>$b); 
} 
return $a; 
} 
// discard bits beyonds 32 bit. 
function trunkbitForce32bit($n){ 
if(PHP_INT_SIZE <= 4){ 
settype($n,&#39;float&#39;); 
if ( $n < 0 ) $n += 4294967296; 
return $n; 
} 
else{ 
$clearbit = &#39;&#39;; 
for($i=0;$i<PHP_INT_SIZE-4;$i++){ 
$clearbit .= &#39;00&#39;; 
} 
for($i=0;$i<4;$i++){ 
$clearbit .= &#39;ff&#39;; 
} 
return ($n & hexdec($clearbit)); 
} 
} 
function bigxor($m,$n){ 
//if(function_exists(&#39;gmp_init&#39;)){ 
// return floatval(gmp_strval(gmp_xor($m,$n))); 
//} 
//else{ 
return $m ^ $n; 
//} 
} 
function mix($a,$b,$c){ 
$a = trunkbitForce32bit($a); 
$b = trunkbitForce32bit($b); 
$c = trunkbitForce32bit($c); 
$a -= $b; $a = trunkbitForce32bit($a); 
$a -= $c; $a = trunkbitForce32bit($a); 
$a = bigxor($a,(zeroFill($c,13))); $a = trunkbitForce32bit($a); 
$b -= $c; $b = trunkbitForce32bit($b); 
$b -= $a; $b = trunkbitForce32bit($b); 
$b = bigxor($b,trunkbitForce32bit($a<<8)); $b = trunkbitForce32bit($b); 
$c -= $a; $c = trunkbitForce32bit($c); 
$c -= $b; $c = trunkbitForce32bit($c); 
$c = bigxor($c,(zeroFill($b,13))); $c = trunkbitForce32bit($c); 
$a -= $b;$a = trunkbitForce32bit($a); 
$a -= $c;$a = trunkbitForce32bit($a); 
$a = bigxor($a,(zeroFill($c,12)));$a = trunkbitForce32bit($a); 
$b -= $c;$b = trunkbitForce32bit($b); 
$b -= $a;$b = trunkbitForce32bit($b); 
$b = bigxor($b,trunkbitForce32bit($a<<16)); 
$c -= $a; $c = trunkbitForce32bit($c); 
$c -= $b; $c = trunkbitForce32bit($c); 
$c = bigxor($c,(zeroFill($b,5))); $c = trunkbitForce32bit($c); 
$a -= $b;$a = trunkbitForce32bit($a); 
$a -= $c;$a = trunkbitForce32bit($a); 
$a = bigxor($a,(zeroFill($c,3)));$a = trunkbitForce32bit($a); 
$b -= $c;$b = trunkbitForce32bit($b); 
$b -= $a;$b = trunkbitForce32bit($b); 
$b = bigxor($b,trunkbitForce32bit($a<<10)); 
$c -= $a; $c = trunkbitForce32bit($c); 
$c -= $b; $c = trunkbitForce32bit($c); 
$c = bigxor($c,(zeroFill($b,15))); $c = trunkbitForce32bit($c); 
return array($a,$b,$c); 
} 
function NewGCH($ch){ 
$ch = ( trunkbitForce32bit( ( $ch / 7 ) << 2 ) | 
( ( myfmod( $ch,13 ) ) & 7 ) ); 
$prbuf = array(); 
$prbuf[0] = $ch; 
for( $i = 1; $i < 20; $i++ ) 
{ 
$prbuf[$i] = $prbuf[$i-1] - 9; 
} 
$ch = GCH( c32to8bit( $prbuf ) ); 
return $ch; 
} 
function myfmod($x,$y){ 
$i = floor( $x / $y ); 
return ( $x - $i * $y ); 
} 
function c32to8bit($arr32){ 
$arr8 = array(); 
for( $i = 0; $i < count($arr32); $i++ ) { 
for( $bitOrder = $i * 4; 
$bitOrder <= $i * 4 + 3; $bitOrder++ ) { 
$arr8[$bitOrder] = $arr32[$i] & 255; 
$arr32[$i] = zeroFill( $arr32[$i], 8 ); 
} 
} 
return $arr8; 
} 
function GCH($url, $length=null){ 
if(is_null($length)) { 
$length = sizeof($url); 
} 
$init = 0xE6359A60; 
$a = 0x9E3779B9; 
$b = 0x9E3779B9; 
$c = 0xE6359A60; 
$k = 0; 
$len = $length; 
$mixo = array(); 
while( $len >= 12 ){ 
$a += ($url[$k+0] +trunkbitForce32bit($url[$k+1]<<8) 
+trunkbitForce32bit($url[$k+2]<<16) 
+trunkbitForce32bit($url[$k+3]<<24)); 
$b += ($url[$k+4] +trunkbitForce32bit($url[$k+5]<<8) 
+trunkbitForce32bit($url[$k+6]<<16) 
+trunkbitForce32bit($url[$k+7]<<24)); 
$c += ($url[$k+8] +trunkbitForce32bit($url[$k+9]<<8) 
+trunkbitForce32bit($url[$k+10]<<16) 
+trunkbitForce32bit($url[$k+11]<<24)); 
$mixo = mix($a,$b,$c); 
$a = $mixo[0]; $b = $mixo[1]; $c = $mixo[2]; 
$k += 12; 
$len -= 12; 
} 
$c += $length; 
switch( $len ) { 
case 11: 
$c += trunkbitForce32bit($url[$k+10]<<24); 
case 10: 
$c+=trunkbitForce32bit($url[$k+9]<<16); 
case 9 : 
$c+=trunkbitForce32bit($url[$k+8]<<8); 
case 8 : 
$b+=trunkbitForce32bit($url[$k+7]<<24); 
case 7 : 
$b+=trunkbitForce32bit($url[$k+6]<<16); 
case 6 : 
$b+=trunkbitForce32bit($url[$k+5]<<8); 
case 5 : 
$b+=trunkbitForce32bit($url[$k+4]); 
case 4 : 
$a+=trunkbitForce32bit($url[$k+3]<<24); 
case 3 : 
$a+=trunkbitForce32bit($url[$k+2]<<16); 
case 2 : 
$a+=trunkbitForce32bit($url[$k+1]<<8); 
case 1 : 
$a+=trunkbitForce32bit($url[$k+0]); 
} 
$mixo = mix( $a, $b, $c ); 
$mixo[2] = trunkbitForce32bit($mixo[2]); 
if( $mixo[2] < 0 ){ 
return ( 
hexdec(&#39;1&#39;. 
implode(&#39;&#39;, 
array_fill(0,PHP_INT_SIZE*2,&#39;0&#39;))) 
+ $mixo[2] ); 
} 
else{ 
return $mixo[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; 
} 
// return url page content or false if failed. 
function retrieveURLContent($url,$gettype){ 
switch($gettype){ 
case G_PR_GET_TYPE_FILE: 
return retrieveURLContentByFile($url); 
break; 
default: 
return retrieveURLContentBySocket($url); 
break; 
} 
} 
function retrieveURLContentByFile($url){ 
$fd = @fopen($url,"r"); 
if(!$fd){ 
return false; 
} 
$result = ""; 
while($buffer = fgets($fd, 4096)) { 
$result .= $buffer; 
} 
fclose($fd); 
return $result; 
} 
function retrieveURLContentBySocket($url, 
$host="", 
$port=80, 
$timeout=30){ 
if($host == ""){ 
if(!($pos = strpos($url,&#39;://&#39;))){ 
return false; 
} 
$host = substr( $url, 
$pos+3, 
strpos($url,&#39;/&#39;,$pos+3) - $pos - 3); 
$uri = substr($url,strpos($url,&#39;/&#39;,$pos+3)); 
} 
else{ 
$uri = $url; 
} 
$request = "GET ".$uri." HTTP/1.0\r\n" 
."Host: ".$host."\r\n" 
."Accept: */*\r\n" 
."User-Agent: ZealGet\r\n" 
."\r\n"; 
$sHnd = @fsockopen ($host, $port, $errno, $errstr, $timeout); 
if(!$sHnd){ 
return false; 
} 
@fputs ($sHnd, $request); 
// Get source 
$result = ""; 
while (!feof($sHnd)){ 
$result .= fgets($sHnd,4096); 
} 
fclose($sHnd); 
$headerend = strpos($result,"\r\n\r\n"); 
if (is_bool($headerend)) 
{ 
return $result; 
} 
else{ 
return substr($result,$headerend+4); 
} 
}
声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
您如何防止与会议有关的跨站点脚本(XSS)攻击?您如何防止与会议有关的跨站点脚本(XSS)攻击?Apr 23, 2025 am 12:16 AM

要保护应用免受与会话相关的XSS攻击,需采取以下措施:1.设置HttpOnly和Secure标志保护会话cookie。2.对所有用户输入进行输出编码。3.实施内容安全策略(CSP)限制脚本来源。通过这些策略,可以有效防护会话相关的XSS攻击,确保用户数据安全。

您如何优化PHP会话性能?您如何优化PHP会话性能?Apr 23, 2025 am 12:13 AM

优化PHP会话性能的方法包括:1.延迟会话启动,2.使用数据库存储会话,3.压缩会话数据,4.管理会话生命周期,5.实现会话共享。这些策略能显着提升应用在高并发环境下的效率。

什么是session.gc_maxlifetime配置设置?什么是session.gc_maxlifetime配置设置?Apr 23, 2025 am 12:10 AM

thesession.gc_maxlifetimesettinginphpdeterminesthelifespanofsessiondata,setInSeconds.1)它'sconfiguredinphp.iniorviaini_set().2)abalanceIsiseededeedeedeedeedeedeedto to to avoidperformance andununununununexpectedLogOgouts.3)

您如何在PHP中配置会话名?您如何在PHP中配置会话名?Apr 23, 2025 am 12:08 AM

在PHP中,可以使用session_name()函数配置会话名称。具体步骤如下:1.使用session_name()函数设置会话名称,例如session_name("my_session")。2.在设置会话名称后,调用session_start()启动会话。配置会话名称可以避免多应用间的会话数据冲突,并增强安全性,但需注意会话名称的唯一性、安全性、长度和设置时机。

您应该多久再生一次会话ID?您应该多久再生一次会话ID?Apr 23, 2025 am 12:03 AM

会话ID应在登录时、敏感操作前和每30分钟定期重新生成。1.登录时重新生成会话ID可防会话固定攻击。2.敏感操作前重新生成提高安全性。3.定期重新生成降低长期利用风险,但需权衡用户体验。

如何在PHP中设置会话cookie参数?如何在PHP中设置会话cookie参数?Apr 22, 2025 pm 05:33 PM

在PHP中设置会话cookie参数可以通过session_set_cookie_params()函数实现。1)使用该函数设置参数,如过期时间、路径、域名、安全标志等;2)调用session_start()使参数生效;3)根据需求动态调整参数,如用户登录状态;4)注意设置secure和httponly标志以提升安全性。

在PHP中使用会议的主要目的是什么?在PHP中使用会议的主要目的是什么?Apr 22, 2025 pm 05:25 PM

在PHP中使用会话的主要目的是维护用户在不同页面之间的状态。1)会话通过session_start()函数启动,创建唯一会话ID并存储在用户cookie中。2)会话数据保存在服务器上,允许在不同请求间传递数据,如登录状态和购物车内容。

您如何在子域中分享会议?您如何在子域中分享会议?Apr 22, 2025 pm 05:21 PM

如何在子域名间共享会话?通过设置通用域名的会话cookie实现。1.在服务器端设置会话cookie的域为.example.com。2.选择合适的会话存储方式,如内存、数据库或分布式缓存。3.通过cookie传递会话ID,服务器根据ID检索和更新会话数据。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )专业的PHP集成开发工具

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具