using System;
using System.IO;
using System.Collections;
using System.Diagnostics;
using System.Web;
using System.Net;
namespace WebKeySoft.Net
{
///
/// Summary description for GoogleRanker.
///
public class GoogleRanker
{
#region Private members
private const uint GOOGLE_MAGIC = 0xE6359A60;
private UriEx url;
#endregion
#region Public properties
public UriEx Url
{
get { return url; }
set { url = value; }
}
public int Rank
{
get { return this.getRank(url); }
}
public uint CheckSum
{
get { return this.GoogleCH(this.strord("info:"+url.AbsoluteUri)); }
}
#endregion
#region Constructor
public GoogleRanker(UriEx url)
{
this.url = url;
}
#endregion
#region Private methods
private uint GoogleCH(uint [] url)
{
return GoogleCH(url, null);
}
private uint GoogleCH(uint [] url, object length)
{
return GoogleCH(url, length, GOOGLE_MAGIC);
}
private uint GoogleCH(uint [] url, object l, uint init)
{
uint a, b, c, k, len, length;
uint [] mix;
if (l == null)
length = Convert.ToUInt32(url.Length);
else
length = (uint)l;
a = b = Convert.ToUInt32(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 = _mix(a,b,c);
a = mix[0]; b = mix[1]; c = mix[2];
k += 12;
len -= 12;
}
c += length;
switch(len) /* all the case statements fall through */
{
case 11: c+=(url[k+10]<<24);
c+=(url[k+9]<<16);
c+=(url[k+8]<<8);
b+=(url[k+7]<<24);
b+=(url[k+6]<<16);
b+=(url[k+5]<<8);
b+=(url[k+4]);
a+=(url[k+3]<<24);
a+=(url[k+2]<<16);
a+=(url[k+1]<<8);
a+=(url[k+0]);
break;
case 10: c+=(url[k+9]<<16);
c+=(url[k+8]<<8);
b+=(url[k+7]<<24);
b+=(url[k+6]<<16);
b+=(url[k+5]<<8);
b+=(url[k+4]);
a+=(url[k+3]<<24);
a+=(url[k+2]<<16);
a+=(url[k+1]<<8);
a+=(url[k+0]);
break;
case 9 : c+=(url[k+8]<<8);
b+=(url[k+7]<<24);
b+=(url[k+6]<<16);
b+=(url[k+5]<<8);
b+=(url[k+4]);
a+=(url[k+3]<<24);
a+=(url[k+2]<<16);
a+=(url[k+1]<<8);
a+=(url[k+0]);
break;
case 8 : b+=(url[k+7]<<24);
b+=(url[k+6]<<16);
b+=(url[k+5]<<8);
b+=(url[k+4]);
a+=(url[k+3]<<24);
a+=(url[k+2]<<16);
a+=(url[k+1]<<8);
a+=(url[k+0]);
break;
case 7 : b+=(url[k+6]<<16);
b+=(url[k+5]<<8);
b+=(url[k+4]);
a+=(url[k+3]<<24);
a+=(url[k+2]<<16);
a+=(url[k+1]<<8);
a+=(url[k+0]);
break;
case 6 : b+=(url[k+5]<<8);
b+=(url[k+4]);
a+=(url[k+3]<<24);
a+=(url[k+2]<<16);
a+=(url[k+1]<<8);
a+=(url[k+0]);
break;
case 5 : b+=(url[k+4]);
a+=(url[k+3]<<24);
a+=(url[k+2]<<16);
a+=(url[k+1]<<8);
a+=(url[k+0]);
break;
case 4 : a+=(url[k+3]<<24);
a+=(url[k+2]<<16);
a+=(url[k+1]<<8);
a+=(url[k+0]);
break;
case 3 : a+=(url[k+2]<<16);
a+=(url[k+1]<<8);
a+=(url[k+0]);
break;
case 2 : a+=(url[k+1]<<8);
a+=(url[k+0]);
break;
case 1 : a+=(url[k+0]);
break;
/* case 0: nothing left to add */
}
mix = _mix(a,b,c);
/*-------------------------------------------- report the result */
return mix[2];
}
private uint zeroFill(uint a, uint b)
{
uint ubase1 = 2147483648;
uint ubase2 = 0x40000000;
int un = 1;
uint z = ubase1;
if ((z & a) != 0)
{
a = (a>>1);
a &= (~z);
a |= ubase2;
a = (a>>((int)b-un));
//Debug.WriteLine("b="+b);
}
else
{
a = (a>>(int)b);
}
return a;
}
private uint[] _mix(uint a, uint b, uint c)
{
a -= b; a -= c; a ^= zeroFill(c,13);
b -= c; b -= a; b ^= (a<<8);
c -= a; c -= b; c ^= (zeroFill(b,13));
a -= b; a -= c; a ^= (zeroFill(c,12));
b -= c; b -= a; b ^= (a<<16);
c -= a; c -= b; c ^= (zeroFill(b,5));
a -= b; a -= c; a ^= (zeroFill(c,3));
b -= c; b -= a; b ^= (a<<10);
c -= a; c -= b; c ^= (zeroFill(b,15));
return new uint[]{a,b,c};
}
private uint [] strord(string str)
{
uint [] result = new uint[str.Length];
for(int i=0;i