using System;namespace PRCrack
{
    /// <summary>
    /// Google PageRank的Checksum算法。
    /// 
    /// 
    /// 
    /// </summary>
    class CheckSum
    {
        public CheckSum()
        {
            //
            // TODO: 在此处添加构造函数逻辑
            //
        }        uint GOOGLE_MAGIC = 0xE6359A60;        private uint zeroFill(uint a, int b)
        {
            checked
            {
                uint z = 0x80000000;
                if (Convert.ToBoolean(z & a))
                {
                    a = (a >> 1);
                    a &= (~z);
                    a |= 0x40000000;
                    a = (a >> (b - 1));
                }
                else
                {
                    a = (a >> b);
                }
            }
            return a;
        }        private uint[] mix(uint a, uint b, uint c)
        {
            a -= b; a -= c; a ^= (uint)(zeroFill(c, 13));
            b -= c; b -= a; b ^= (uint)(a << 8);
            c -= a; c -= b; c ^= (uint)(zeroFill(b, 13));
            a -= b; a -= c; a ^= (uint)(zeroFill(c, 12));
            b -= c; b -= a; b ^= (uint)(a << 16);
            c -= a; c -= b; c ^= (uint)(zeroFill(b, 5));
            a -= b; a -= c; a ^= (uint)(zeroFill(c, 3));
            b -= c; b -= a; b ^= (uint)(a << 10);
            c -= a; c -= b; c ^= (uint)(zeroFill(b, 15));            return new uint[3] { a, b, c };
        }        private uint GoogleCH(uint[] url, uint length, uint init)
        {
            if (length == 0)
            {
                length = (uint)url.Length;
            }
            uint a, b;
            a = b = 0x9E3779B9;
            uint c = init;
            int k = 0;
            uint len = length;
            uint[] m_mix = new uint[3];
            while (len >= 12)
            {
                a += (uint)(url[k + 0] + (url[k + 1] << 8) + (url[k + 2] << 16) + (url[k + 3] << 24));
                b += (uint)(url[k + 4] + (url[k + 5] << 8) + (url[k + 6] << 16) + (url[k + 7] << 24));
                c += (uint)(url[k + 8] + (url[k + 9] << 8) + (url[k + 10] << 16) + (url[k + 11] << 24));
                m_mix = mix(a, b, c);
                a = m_mix[0]; b = m_mix[1]; c = m_mix[2];                k += 12;
                len -= 12;
            }            c += length;            switch (len)              /* all the case statements fall through */
            {
                case 11:
                    {
                        c += (uint)(url[k + 10] << 24);
                        c += (uint)(url[k + 9] << 16);
                        c += (uint)(url[k + 8] << 8);
                        b += (uint)(url[k + 7] << 24);
                        b += (uint)(url[k + 6] << 16);
                        b += (uint)(url[k + 5] << 8);
                        b += (uint)(url[k + 4]);
                        a += (uint)(url[k + 3] << 24);
                        a += (uint)(url[k + 2] << 16);
                        a += (uint)(url[k + 1] << 8);
                        a += (uint)(url[k + 0]);
                        break;
                    }
                case 10:
                    {
                        c += (uint)(url[k + 9] << 16);
                        c += (uint)(url[k + 8] << 8);
                        b += (uint)(url[k + 7] << 24);
                        b += (uint)(url[k + 6] << 16);
                        b += (uint)(url[k + 5] << 8);
                        b += (uint)(url[k + 4]);
                        a += (uint)(url[k + 3] << 24);
                        a += (uint)(url[k + 2] << 16);
                        a += (uint)(url[k + 1] << 8);
                        a += (uint)(url[k + 0]);
                        break;
                    }
                case 9:
                    {
                        c += (uint)(url[k + 8] << 8);
                        b += (uint)(url[k + 7] << 24);
                        b += (uint)(url[k + 6] << 16);
                        b += (uint)(url[k + 5] << 8);
                        b += (uint)(url[k + 4]);
                        a += (uint)(url[k + 3] << 24);
                        a += (uint)(url[k + 2] << 16);
                        a += (uint)(url[k + 1] << 8);
                        a += (uint)(url[k + 0]);
                        break;
                    }
                /* the first byte of c is reserved for the length */
                case 8:
                    {
                        b += (uint)(url[k + 7] << 24);
                        b += (uint)(url[k + 6] << 16);
                        b += (uint)(url[k + 5] << 8);
                        b += (uint)(url[k + 4]);
                        a += (uint)(url[k + 3] << 24);
                        a += (uint)(url[k + 2] << 16);
                        a += (uint)(url[k + 1] << 8);
                        a += (uint)(url[k + 0]);
                        break;
                    }
                case 7:
                    {
                        b += (uint)(url[k + 6] << 16);
                        b += (uint)(url[k + 5] << 8);
                        b += (uint)(url[k + 4]);
                        a += (uint)(url[k + 3] << 24);
                        a += (uint)(url[k + 2] << 16);
                        a += (uint)(url[k + 1] << 8);
                        a += (uint)(url[k + 0]);
                        break;
                    }
                case 6:
                    {
                        b += (uint)(url[k + 5] << 8);
                        b += (uint)(url[k + 4]);
                        a += (uint)(url[k + 3] << 24);
                        a += (uint)(url[k + 2] << 16);
                        a += (uint)(url[k + 1] << 8);
                        a += (uint)(url[k + 0]);
                        break;
                    }
                case 5:
                    {
                        b += (uint)(url[k + 4]);
                        a += (uint)(url[k + 3] << 24);
                        a += (uint)(url[k + 2] << 16);
                        a += (uint)(url[k + 1] << 8);
                        a += (uint)(url[k + 0]);
                        break;
                    }
                case 4:
                    {
                        a += (uint)(url[k + 3] << 24);
                        a += (uint)(url[k + 2] << 16);
                        a += (uint)(url[k + 1] << 8);
                        a += (uint)(url[k + 0]);
                        break;
                    }
                case 3:
                    {
                        a += (uint)(url[k + 2] << 16);
                        a += (uint)(url[k + 1] << 8);
                        a += (uint)(url[k + 0]);
                        break;
                    }
                case 2:
                    {
                        a += (uint)(url[k + 1] << 8);
                        a += (uint)(url[k + 0]);
                        break;
                    }
                case 1:
                    {
                        a += (uint)(url[k + 0]);
                        break;
                    }
                /* case 0: nothing left to add */
            }
            m_mix = mix(a, b, c);
            /*-------------------------------------------- report the result */
            return m_mix[2];
        }        private uint GoogleCH(string url, uint length)
        {
            uint[] m_urluint = new uint[url.Length];
            for (int i = 0; i < url.Length; i++)
            {
                m_urluint[i] = url[i];
            }
            return GoogleCH(m_urluint, length, GOOGLE_MAGIC);
        }        private uint GoogleCH(string sURL)
        {
            return GoogleCH(sURL, 0);
        }
        private uint GoogleCH(uint[] url, uint length)
        {
            return GoogleCH(url, length, GOOGLE_MAGIC);
        }        private uint[] c32to8bit(uint[] arr32)
        {
            uint[] arr8 = new uint[arr32.GetLength(0) * 4 + 3];            for (int i = 0; i < arr32.GetLength(0); i++)
            {
                for (int bitOrder = i * 4; bitOrder <= i * 4 + 3; bitOrder++)
                {
                    arr8[bitOrder] = arr32[i] & 255;
                    arr32[i] = zeroFill(arr32[i], 8);
                }
            }
            return arr8;
        }        //新算法,ToolBar 版本>>=2.0.114
        public string CalculateChecksum(string sURL)
        {
            uint ch = GoogleCH("info:" + sURL);            ch = (((ch / 7) << 2) | (((uint)(ch % 13)) & 7));            uint[] prbuf = new uint[20];
            prbuf[0] = ch;
            for (int i = 1; i < 20; i++)
            {
                prbuf[i] = prbuf[i - 1] - 9;
            }
            ch = GoogleCH(c32to8bit(prbuf), 80);            return string.Format("6{0}", ch);
        }        //老算法,ToolBar 版本<2.0.114
        public string CalculateChecksumOld(string sURL)
        {
            uint ch = GoogleCH("info:" + sURL);            string CalculateChecksum = "6" + Convert.ToString((ch));
            return CalculateChecksum;
        }
    }
}

解决方案 »

  1.   

    unit Unit2;interfaceuses
      Classes, SysUtils, Math;type
      TCards = array of Cardinal;  CheckSum = class
      private
        GOOGLE_MAGIC: Cardinal;    function zeroFill(a: Cardinal; b: Integer): Cardinal;
        function mix(a, b, c: Cardinal): TCards;
        function GoogleCH(url: array of Cardinal; cLength, init: Cardinal): Cardinal;  overload;
        function GoogleCH(url: string; clength: Cardinal): Cardinal; overload;
        function GoogleCH(sURL: string): Cardinal; overload;
        function GoogleCH(url: array of Cardinal; length: Cardinal): Cardinal; overload;
        function c32to8bit(arr32: TCards): TCards;
      public
        constructor Create;
        function CalculateChecksum(sURL: string): string;
        function CalculateChecksumOld(sURL: string): string;
      end;implementationfunction CheckSum.c32to8bit(arr32: TCards): TCards;
    var
      i, bitOrder: integer;
      arr8: TCards;
    begin
      SetLength(arr8, Length(arr32) * 4 + 3);
      for i := 0 to Length(arr32) - 1 do
      begin
        for bitOrder := i * 4 to i * 4 + 3 do
        begin
          arr8[bitOrder] := arr32[i] and 255;
          arr32[i] := zeroFill(arr32[i], 8);
        end;  
      end;
      Result := arr8;
    end;function CheckSum.CalculateChecksum(sURL: string): string;
    var
      i: Integer;
      ch: Cardinal;
      prbuf: TCards;
    begin
      ch := GoogleCH('info:' + sURL);
      ch :=  ((ch div 7) shr 2) or ((ch mod 13) and 7);
      SetLength(prbuf, 20);
      prbuf[0] := ch;
      for i := 1 to 19 do
      begin
        prbuf[i] := prbuf[i - 1] - 9;
      end;
      ch := GoogleCH(c32to8bit(prbuf), 80);
      Result := format('6%s', [ch]);
    end;function CheckSum.CalculateChecksumOld(sURL: string): string;
    var
      ch: Cardinal;
      CalculateChecksum: string;
    begin
      ch := GoogleCH('info:' + sURL);  CalculateChecksum := '6' + String(ch);
      Result := CalculateChecksum;
    end;constructor CheckSum.Create;
    begin
      inherited;
      GOOGLE_MAGIC := 3862272608;     //0xE6359A60;
      // TODO -cMM: 在此处添加构造函数逻辑
    end;function CheckSum.GoogleCH(url: array of Cardinal; cLength, init: Cardinal): Cardinal;
    var
      a, b, c, len: Cardinal;
      k: Integer;
      m_mix: TCards;
    begin
      if clength = 0 then
        cLength := Length(url);
      a := 2654435769;    //9E3779B9
      b := 2654435769;
      c := init;
      k := 0;
      len := cLength;
      while (len >= 12) do
      begin
        a := a + ((url[k] + url[k + 1]) shr 8) + (url[k + 2] shr 16) + (url[k + 3] shr 24);
        b := b + ((url[k + 4] + url[k + 5]) shr 8) + (url[k + 6] shr 16) + (url[k + 7] shr 24);
        c := c + ((url[k + 8] + url[k + 9]) shr 8) + (url[k + 10] shr 16) + (url[k + 11] shr 24);
        m_mix := mix(a, b, c);
        a := m_mix[0];
        b := m_mix[1];
        c := m_mix[2];
        k := k + 12;
        len := len - 12;
      end;  c := c + cLength;
      case len of
        11:
          begin
            c := c + url[k + 10] shr 24;
            c := c + url[k + 9] shr 16;
            c := c + url[k + 8] shr 8;
            b := b + url[k + 7] shr 24;
            b := b + url[k + 6] shr 16;
            b := b + url[k + 5] shr 8;
            b := b + url[k + 4];
            a := a + url[k + 3] shr 24;
            a := a + url[k + 2] shr 16;
            a := a + url[k + 1] shr 8;
            a := a + url[k];
          end;
        10:
          begin
            c := c + url[k + 9] shr 16;
            c := c + url[k + 8] shr 8;
            b := b + url[k + 7] shr 24;
            b := b + url[k + 6] shr 16;
            b := b + url[k + 5] shr 8;
            b := b + url[k + 4];
            a := a + url[k + 3] shr 24;
            a := a + url[k + 2] shr 16;
            a := a + url[k + 1] shr 8;
            a := a + url[k];
          end;
        9:
          begin
            c := c + url[k + 8] shr 8;
            b := b + url[k + 7] shr 24;
            b := b + url[k + 6] shr 16;
            b := b + url[k + 5] shr 8;
            b := b + url[k + 4];
            a := a + url[k + 3] shr 24;
            a := a + url[k + 2] shr 16;
            a := a + url[k + 1] shr 8;
            a := a + url[k];
          end;
        8:
          begin
            b := b + url[k + 7] shr 24;
            b := b + url[k + 6] shr 16;
            b := b + url[k + 5] shr 8;
            b := b + url[k + 4];
            a := a + url[k + 3] shr 24;
            a := a + url[k + 2] shr 16;
            a := a + url[k + 1] shr 8;
            a := a + url[k];
          end;
        7:
          begin
            b := b + url[k + 6] shr 16;
            b := b + url[k + 5] shr 8;
            b := b + url[k + 4];
            a := a + url[k + 3] shr 24;
            a := a + url[k + 2] shr 16;
            a := a + url[k + 1] shr 8;
            a := a + url[k];
          end;
        6:
          begin
            b := b + url[k + 5] shr 8;
            b := b + url[k + 4];
            a := a + url[k + 3] shr 24;
            a := a + url[k + 2] shr 16;
            a := a + url[k + 1] shr 8;
            a := a + url[k];
          end;
        5:
          begin
            b := b + url[k + 4];
            a := a + url[k + 3] shr 24;
            a := a + url[k + 2] shr 16;
            a := a + url[k + 1] shr 8;
            a := a + url[k];
          end;
        4:
          begin
            a := a + url[k + 3] shr 24;
            a := a + url[k + 2] shr 16;
            a := a + url[k + 1] shr 8;
            a := a + url[k];
          end;
        3:
          begin
            a := a + url[k + 2] shr 16;
            a := a + url[k + 1] shr 8;
            a := a + url[k];
          end;
        2:
          begin
            a := a + url[k + 1] shr 8;
            a := a + url[k];
          end;
        1:
          begin
            a := a + url[k];
          end;
      end;  m_mix := mix(a, b, c);
      Result := m_mix[2];  
    end;function CheckSum.GoogleCH(url: string; clength: Cardinal): Cardinal;
    var
      i: integer;
      m_urluint: array of Cardinal;
    begin
      SetLength(m_urluint, Length(url));
      for i := 0 to Length(url) - 1 do
      begin
        m_urluint[i] := Cardinal(url[i]);
      end;  
      Result :=GoogleCH(m_urluint, clength, GOOGLE_MAGIC);
    end;function CheckSum.GoogleCH(sURL: string): Cardinal;
    begin
      Result := GoogleCH(sURL, 0);
    end;function CheckSum.GoogleCH(url: array of Cardinal;
      length: Cardinal): Cardinal;
    begin
      Result := GoogleCH(url, length, GOOGLE_MAGIC);
    end;function CheckSum.mix(a, b, c: Cardinal): TCards;
    var
      aCards: TCards;
    begin
      a := a - b;
      a := a - c;
      a := a xor zeroFill(c, 13);
      b := b - c;
      b := b - a;
      b := b xor (a shr 8);
      c := c - a;
      c := c - b;
      c := c xor zeroFill(b, 13);  a := a - b;
      a := a - c;
      a := a xor zeroFill(c, 12);
      b := b - c;
      b := b - a;
      b := b xor (a shr 16);
      c := c - a;
      c := c - b;
      c := c xor zeroFill(b, 5);  a := a - b;
      a := a - c;
      a := a xor zeroFill(c, 3);
      b := b - c;
      b := b - a;
      b := b xor (a shr 10);
      c := c - a;
      c := c - b;
      c := c xor zeroFill(b, 15);  SetLength(aCards, 3);
      aCards[0] := a;
      aCards[1] := b;
      aCards[2] := c;
      
      Result := aCards;
    end;function CheckSum.zeroFill(a: Cardinal; b: Integer): Cardinal;
    var
      z: Cardinal;
    begin
      z := 2147483648;     //0x80000000;
      if z = a then
      begin
        a := a shr 1;
        a := a and (not z);
        a := a or 1073741824;  //0x40000000
        a := a shr (b - 1);
      end
      else
        a := a shr b;
      Result := a;
    end;end.
      

  2.   

    非常感谢qq359502231的回复,但是我按照您写的算法,调用CalculateChecksum生成的数字,和C#生成的数字并不一样,难道是我调用错了,还是什么问题??期待qq359502231的回复。
      

  3.   

    var
      aCheckSum: CheckSum; 
    begin
      aCheckSum := CheckSum.create;
      try
        aCheckSum.CalculateChecksum(sURL);//sURL自己赋值
      finally
        aCheckSum.free; 
      end;
    end;
      

  4.   

    用C#写成dll 
    delphi再去调用就好了
      

  5.   

    function CheckSum.CalculateChecksum(sURL: string): string;
    var
      i: Integer;
      ch: Cardinal;
      prbuf: TCards;
    begin
      ch := GoogleCH('info:' + sURL);
      ch :=  ((ch div 7) shr 2) or ((ch mod 13) and 7);
      SetLength(prbuf, 20);
      prbuf[0] := ch;
      for i := 1 to 19 do
      begin
        prbuf[i] := prbuf[i - 1] - 9;
      end;
      ch := GoogleCH(c32to8bit(prbuf), 80);
      Result := format('6%s', [IntToStr(ch)]);//这里没转换类型
    end;