NonSoft

GoogleのPageRank取得用チェックサム(ch)を
計算するサンプル(perl)


 サンプル(ソース/コード)
<このサンプルの概要>
検索エンジン(Google)のPageRankを取得するサンプル(VB.NET)を公開するため、そのサン
プルで必要なPageRank取得用チェックサム(ch)を計算するCGIを作りました。このCGIを作
る際に良いサンプルを参考にさせて頂いたのでURLを記述して置きます。

<チェックサム(ch)を計算するサンプルのURL>
http://blogoscoped.com/archive/2004_06_27_index.html(php版)
http://www.xdelta.net/wiki/Google/PageRank.html(perl版)

しかし、どちらのサンプルもNiftyでは動きませんでした。理由はNiftyがphpを対応して
無い事と、どうやらperlのバージョンが異なる事でした。

頑張って移植を試みたのですが、CheckSum(ch)計算には整数(Unsigned)32ビットの演算が
必要でNiftyのperlではすぐにオーバーフロー(エラー)になってしまいました。結局、
足し算や引き算をオーバーフローしないようにビット演算で計算する必要があり、やっと
出来た感じですが、全てのURLに対応出来ているかは自身がありません。

本サンプルを使用したCGIをお試し頂けます。
GoogleのPageRank取得用CheckSum(ch)計算

関連情報
GoogleのPageRankを取得するサンプル(VB.NET)
Googleの検索順位を取得するサンプル(VB.NET)
サイト内URLチェック(VB.NET/C#.NET用DLL)
サイト内URLチェック(ツール)

★Perlプログラム(PageRankCh.pl)
sub minus($){
  my($a) = @_;
  $a = ~$a + 1;
}

sub add($$){
  my($a, $b) = @_;
  $c = ~(~$a + ~$b) -1;
  $d = $a + $b;
  if( $d >= 0xffffffff + 1 ){
    return $c;
  }else{
    return $d;
  }
}

sub zeroFill($$){ 
  my($a, $b) = @_;
  $z = 0x80000000;
  if ($z & $a){
    $a = ($a>>1);
    $a &= (~$z);
    $a |= 0x40000000;
    $a = ($a>>($b-1));
  }else{
    $a = ($a>>$b);
  }
  return $a;
}

sub mix($$$) {
  my($a, $b, $c) = @_;
  $a = add($a,minus($b)); $a = add($a,minus($c)); $a ^= (zeroFill($c,13));
  $b = add($b,minus($c)); $b = add($b,minus($a)); $b ^= ($a<<8);
  $c = add($c,minus($a)); $c = add($c,minus($b)); $c ^= (zeroFill($b,13));
  $a = add($a,minus($b)); $a = add($a,minus($c)); $a ^= (zeroFill($c,12));
  $b = add($b,minus($c)); $b = add($b,minus($a)); $b ^= ($a<<16);
  $c = add($c,minus($a)); $c = add($c,minus($b)); $c ^= (zeroFill($b,5));
  $a = add($a,minus($b)); $a = add($a,minus($c)); $a ^= (zeroFill($c,3));
  $b = add($b,minus($c)); $b = add($b,minus($a)); $b ^= ($a<<10);
  $c = add($c,minus($a)); $c = add($c,minus($b)); $c ^= (zeroFill($b,15));
  return ($a, $b, $c);
}

sub c2i($$) {
  my($s, $k) = @_;
  my $i = 0;
  if ($k <= length($s)) {
    my @c = unpack('C4', substr($s, $k));
    foreach (0..$#c) { $i += ($c[$_] << ($_ * 8)); }
  }
  return $i;
}

sub GoogleCH($){
  my $url = shift;
  my $len = length($url);
  my @i = (0x9E3779B9, 0x9E3779B9, 0xE6359A60);

  for (my $k = 0; $len >= $k; $k += 12) {
    @i = mix( add($i[0] , c2i($url, $k)),add($i[1] , c2i($url, $k + 4)) , add($i[2] , 
      ( ($k > $len - 12) ? (c2i($url, $k + 8) << 8) + $len : c2i($url, $k + 8)) ));
  }
  return $i[2];
}

$url="http://www.google.co.jp/";
$ch = "";
$url2 = $url;
$url2 =~ s/%([a-fA-Fa0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$ch = GoogleCH("info:" . $url2);
print($ch);