前些日子一篇 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)."\n";
- if ( $a <0 ) $a += 4294967296;
- echo dechex($a)."\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 的问题
使用很简单, 只要在需要的地方
- include_once("./pr.inc.php");
- echo getPR($urlToQuery);
- ?>
即可显示出指定 url 的 PageRank 的数值知道了这个数值再在其基础上模拟出 Google Toolbar 上面的图形化的 pr 显示也就不是难事了实际上实现原理说白了也很简单, 就是传递特定的查询参数到 Google 的搜索引擎, 然后抓取返回的页面内容
演示页面请参见 : Google PageRank Query
- cvs -d :pserver:guest@mozdev.org:/cvs login
- cvs -d :pserver:guest@mozdev.org:/cvs co pagerankstatus
- $a &= (~$z);
- $a |= hexdec('4'.implode('',array_fill(0,PHP_INT_SIZE*2-1,'0')));
- $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,'float');
- if ( $n < 0 ) $n += 4294967296;
- return $n;
- }
- else{
- $clearbit = '';
- for($i=0;$i= 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('1'.
- implode('',
- array_fill(0,PHP_INT_SIZE*2,'0')))
- + $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
来源: https://www.php1.cn/detail/php-4cd5b848c2.html