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