C#的MD5类

来源:互联网 发布:java统计网站在线人数 编辑:程序博客网 时间:2024/06/05 14:40

using System;
using System.Text;
using System.Collections;

namespace CHX.Common.CommonFunctions
{
 /// <summary>
 /// MD5 的摘要说明。
 /// </summary>
 public class MD5
 {
  private const long OFFSET_4 = 4294967296;
  private const long MAXINT_4 = 2147483647;
  private long[] State = new long[] {0,0,0,0,0};
  private long ByteCounter;
  private byte[] ByteBuffer = new byte[64];
  private const int S11  = 7;
  private const int S12  = 12;
  private const int S13  = 17;
  private const int S14  = 22;
  private const int S21  = 5;
  private const int S22  = 9;
  private const int S23  = 14;
  private const int S24  = 20;
  private const int S31  = 4;
  private const int S32  = 11;
  private const int S33  = 16;
  private const int S34  = 23;
  private const int S41  = 6;
  private const int S42  = 10;
  private const int S43  = 15;
  private const int S44  = 21;

  public MD5()
  {
   //
   //
  }

  public string RegisterA
  {
   get
   {
    return(State[1].ToString());
   }
  }

  public string RegisterB
  {
   get
   {
    return(State[2].ToString());
   }
  }

  public string RegisterC
  {
   get
   {
    return(State[3].ToString());
   }
  }

  public string RegisterD
  {
   get
   {
    return(State[4].ToString());
   }
  }

  public string MD5_String_Calc(string SourceString)
  {
   MD5Init();
   MD5Update(LenBIncludeChinese(SourceString),StringToArray(SourceString)); //TODO:加入参数
   MD5Final();
   return(GetValues());
  }

  //TODO:在此加入读入FILE
//  Public Function Md5_File_Calc(InFile As String) As String
//   On Error GoTo errorhandler
//   GoSub begin
//  errorhandler
//   DigestFileToHexStr = ""
//   Exit Function
//
//  begin:
//   Dim FileO As Integer
//   FileO = FreeFile
//   Call FileLen(InFile)
//   Open InFile For Binary Access Read As #FileO
//   MD5Init
//   Do While Not EOF(FileO)
//    Get #FileO, , ByteBuffer
//    If Loc(FileO) < LOF(FileO) Then
//     ByteCounter = ByteCounter + 64
//     MD5Transform ByteBuffer
//    End If
//   Loop
//   ByteCounter = ByteCounter + (LOF(FileO) Mod 64)
//   Close #FileO
//   MD5Final
//   Md5_File_Calc = GetValues
//  End Function


  /// <summary>
  /// 获取字符串长度,如果是双字节,则为2,单字节为1
  /// </summary>
  /// <param name="sString"></param>
  /// <returns></returns>
  private int LenBIncludeChinese(string sString)
  {
   int len = sString.Length;
   byte[] sarr = Encoding.Default.GetBytes(sString);
   return(sarr.Length); 
  }

  private byte[] StringToArray(string InString)
  {
   byte[] byteBuffer = new byte[LenBIncludeChinese(InString)];
   byteBuffer = Encoding.Default.GetBytes(InString);
   return(byteBuffer);
  }

  public string GetValues()
  {
   return(LongToString(State[1]) + LongToString(State[2]) + LongToString(State[3]) + LongToString(State[4]));
  }

  private string LongToString(long Num)
  {
   byte A;
   byte B;
   byte C;
   byte D;

   long i;
   string s;


   i = Num & 0xFF;

   A = Byte.Parse(i.ToString());


   if(A<16)
   {
    s = "0" + A.ToString("X");
   }
   else
   {
    s = A.ToString("X");
   }

   i = (long)(Num & 0xFF00) / 256;

   B = Byte.Parse(i.ToString());

   if(B<16)
   {
    s = s + "0" + B.ToString("X");
   }
   else
   {
    s = s + B.ToString("X");
   }

   i = (long)(Num & 0xFF000) / 65536;

   C = Byte.Parse(i.ToString());

   if(C<16)
   {
    s = s + "0" + C.ToString("X");
   }
   else
   {
    s = s + C.ToString("X");
   }

   if(Num<0)
   {
    i = ((long)(Num & 0x7F000000) / 16777216) | 0x80;
    D = Byte.Parse(i.ToString());
   }
   else
   {
    i = (long)(Num & 0xFF000000)/16777216;
    D = Byte.Parse(i.ToString());
   }

   if(D<16)
   {
    s = s + "0" + D.ToString("X");
   }
   else
   {
    s = s + D.ToString("X");
   }

   return(s);
  }

  public void MD5Init()
  {
   ByteCounter = 0;
   State[1] = UnsignedToLong(1732584193);
   State[2] = UnsignedToLong(4023233417);
   State[3] = UnsignedToLong(2562383102);
   State[4] = UnsignedToLong(271733878);
  }

  public void MD5Final()
  {
   double dblBits;
   byte[] padding = new byte[72];
   long lngBytesBuffered;
   long i;

   padding[0]=0x80;
   dblBits = ByteCounter * 8;
   lngBytesBuffered = ByteCounter % 64;
   if(lngBytesBuffered <= 56)
   {
    MD5Update(56 - lngBytesBuffered,padding);
   }
   else
   {
    MD5Update(120 - ByteCounter,padding);
   }
   i=UnsignedToLong(dblBits) & 0xFF;

   padding[0] = Byte.Parse(i.ToString());

   i=((long)UnsignedToLong(dblBits)/256) & 0xFF;
   padding[1] = Byte.Parse(i.ToString());

   i=((long)UnsignedToLong(dblBits)/65536) & 0xFF;

   padding[2] = Byte.Parse(i.ToString());

   i=((long)UnsignedToLong(dblBits)/16777216) & 0xFF;

   padding[3] = Byte.Parse(i.ToString());
   padding[4]=0;
   padding[5]=0;
   padding[6]=0;
   padding[7]=0;

   MD5Update(8,padding);
  }

  public void MD5Update(long InputLen,byte[] InputBuffer)
  {
   int II;
   int I;
   int J;
   int K;
   long lngBufferedBytes;
   long lngBufferRemaining;
   long lngRem;

   lngBufferedBytes = ByteCounter % 64;
   lngBufferRemaining = 64 - lngBufferedBytes;

   ByteCounter += InputLen;

   if(InputLen >= lngBufferRemaining)
   {
    for(II=0;II<lngBufferRemaining;II++)
    {
     ByteBuffer[lngBufferedBytes + II] = InputBuffer[II];
    }

    MD5Transform(ByteBuffer);

    lngRem = (InputLen) % 64;

    for(I=(int)lngBufferRemaining;I<=InputLen - II - lngRem;I+=64)
    {
     for(J=0;J<64;J++)
     {
      ByteBuffer[J] = InputBuffer[I+J];
     }
     MD5Transform(ByteBuffer);
    }

    lngBufferedBytes = 0;
   }
   else
   {
    I = 0;
   }

   for(K=0;K<=InputLen - I - 1;K++)
   {
    ByteBuffer[lngBufferedBytes + K] = InputBuffer[I+K];
   }
  }

  private void MD5Transform(byte[] Buffer)
  {
   long[] X = new long[16];
   long A;
   long B;
   long C;
   long D;

   A = State[1];
   B = State[2];
   C = State[3];
   D = State[4];

   Decode(64,X,Buffer);

   FF(ref A,B,C,D,X[0],S11,-680876936);
   FF(ref D,A,B,C,X[1],S12,-389564586);
   FF(ref C,D,A,B,X[2],S13,606105819);
   FF(ref B,C,D,A,X[3],S14,-1044525330);
   FF(ref A,B,C,D,X[4],S11,-176418897);
   FF(ref D,A,B,C,X[5],S12,1200080426);
   FF(ref C,D,A,B,X[6],S13,-1473231341);
   FF(ref B,C,D,A,X[7],S14,-45705983);
   FF(ref A,B,C,D,X[8],S11,1770035416);
   FF(ref D,A,B,C,X[9],S12,-1958414417);
   FF(ref C,D,A,B,X[10],S13,-42063);
   FF(ref B,C,D,A,X[11],S14,-1990404162);
   FF(ref A,B,C,D,X[12],S11,1804603682);
   FF(ref D,A,B,C,X[13],S12,-40341101);
   FF(ref C,D,A,B,X[14],S13,-1502002290);
   FF(ref B,C,D,A,X[15],S14,1236535329);

   GG(ref A,B,C,D,X[1],S21,-165796510);
   GG(ref D,A,B,C,X[6],S22,-1069501632);
   GG(ref C,D,A,B,X[11],S23,643717713);
   GG(ref B,C,D,A,X[0],S24,-373897302);
   GG(ref A,B,C,D,X[5],S21,-701558691);
   GG(ref D,A,B,C,X[10],S22,38016083);
   GG(ref C,D,A,B,X[15],S23,-660478335);
   GG(ref B,C,D,A,X[4],S24,-405537848);
   GG(ref A,B,C,D,X[9],S21,568446438);
   GG(ref D,A,B,C,X[14],S22,-1019803690);
   GG(ref C,D,A,B,X[3],S23,-187363961);
   GG(ref B,C,D,A,X[8],S24,1163531501);
   GG(ref A,B,C,D,X[13],S21,-1444681467);
   GG(ref D,A,B,C,X[2],S22,-51403784);
   GG(ref C,D,A,B,X[7],S23,1735328473);
   GG(ref B,C,D,A,X[12],S24,-1926607734);

   HH(ref A,B,C,D,X[5],S31,-378558);
   HH(ref D,A,B,C,X[8],S32,-2022574463);
   HH(ref C,D,A,B,X[11],S33,1839030562);
   HH(ref B,C,D,A,X[14],S34,-35309556);
   HH(ref A,B,C,D,X[1],S31,-1530992060);
   HH(ref D,A,B,C,X[4],S32,1272893353);
   HH(ref C,D,A,B,X[7],S33,-155497632);
   HH(ref B,C,D,A,X[10],S34,-1094730640);
   HH(ref A,B,C,D,X[13],S31,681279174);
   HH(ref D,A,B,C,X[0],S32,-358537222);
   HH(ref C,D,A,B,X[3],S33,-722521979);
   HH(ref B,C,D,A,X[6],S34,76029189);
   HH(ref A,B,C,D,X[9],S31,-640364487);
   HH(ref D,A,B,C,X[12],S32,-421815835);
   HH(ref C,D,A,B,X[15],S33,530742520);
   HH(ref B,C,D,A,X[2],S34,-995338651);

   II(ref A,B,C,D,X[0],S41,-198630844);
   II(ref D,A,B,C,X[7],S42,1126891415);
   II(ref C,D,A,B,X[14],S43,-1416354905);
   II(ref B,C,D,A,X[5],S44,-57434055);
   II(ref A,B,C,D,X[12],S41,1700485571);
   II(ref D,A,B,C,X[3],S42,-1894986606);
   II(ref C,D,A,B,X[10],S43,-1051523);
   II(ref B,C,D,A,X[1],S44,-2054922799);
   II(ref A,B,C,D,X[8],S41,1873313359);
   II(ref D,A,B,C,X[15],S42,-30611744);
   II(ref C,D,A,B,X[6],S43,-1560198380);
   II(ref B,C,D,A,X[13],S44,1309151649);
   II(ref A,B,C,D,X[4],S41,-145523070);
   II(ref D,A,B,C,X[11],S42,-1120210379);
   II(ref C,D,A,B,X[2],S43,718787259);
   II(ref B,C,D,A,X[9],S44,-343485551);

   State[1]=LongOverflowAdd(State[1],A);
   State[2]=LongOverflowAdd(State[2],B);
   State[3]=LongOverflowAdd(State[3],C);
   State[4]=LongOverflowAdd(State[4],D);

  }

  private void Decode(int Length,long[] OutputBuffer,byte[] InputBuffer)
  {
   
   int intByteIndex = 0;

   int intDblIndex = 0;

   double dblSum;
   for(intByteIndex = 0;intByteIndex<Length;intByteIndex+=4)
   {
    dblSum = InputBuffer[intByteIndex] + InputBuffer[intByteIndex + 1]*256 + InputBuffer[intByteIndex+2]*65536 + InputBuffer[intByteIndex+3]*16777216;
    OutputBuffer[intDblIndex]=UnsignedToLong(dblSum);
    intDblIndex ++;
   }
  }

  private void FF(ref long A,long B,long C,long D,long X,long S,long ac)
  {
   A = LongOverflowAdd4(A,(B & C) | (~(B) & D),X,ac);
   A = LongLeftRotate(A,S);
   A = LongOverflowAdd(A,B);
  }

  private void GG(ref long A,long B,long C,long D,long X,long S,long ac)
  {
   A = LongOverflowAdd4(A,(B & D) | (C & ~D),X,ac);
   A = LongLeftRotate(A,S);
   A = LongOverflowAdd(A,B);
  }

  private void HH(ref long A,long B,long C,long D,long X,long S,long ac)
  {
   A = LongOverflowAdd4(A,B^C^D,X,ac);
   A = LongLeftRotate(A,S);
   A = LongOverflowAdd(A,B);
  }

  private void II(ref long A,long B,long C,long D,long X,long S,long ac)
  {
   A = LongOverflowAdd4(A,C^(B | ~D),X,ac);
   A = LongLeftRotate(A,S);
   A = LongOverflowAdd(A,B);
  }

  public long LongLeftRotate(long Value,long Bits)
  {
   long lngSign;
   long lngI;
   Bits %= 32;
   if(Bits == 0)
   {
    return(Value);
   }

   for(lngI = 1;lngI<=Bits;lngI++)
   {
    lngSign = Value & 0xC0000000;
    Value = (Value & 0x3FFFFFFF)*2;
    bool b;
    b = (lngSign < 0);
    long l;
    if(b==true)
     l=1;
    else
     l=0;
    Value = Value | (l & 1) | ((lngSign & 0x40000000) & 0x80000000);
   }
   return(Value);
  }

  private long LongOverflowAdd(long Val1,long Val2)
  {
   long lngHighWord;
   long lngLowWord;
   long lngOverflow;

   lngLowWord = (Val1 & 0xFFFF) + (Val2 & 0xFFFF);
   lngOverflow = (long)lngLowWord/65536;
   lngHighWord = ((long)((Val1 & 0xFFFF0000)/65536) + ((long)(Val2 & 0xFFFF0000)/65536) + lngOverflow) & 0xFFFF;
   return(UnsignedToLong((lngHighWord*65536) + (lngLowWord & 0xFFFF)));
  }

  private long LongOverflowAdd4(long Val1,long Val2,long Val3,long Val4)
  {
   long lngHighWord;
   long lngLowWord;
   long lngOverflow;

   lngLowWord = (Val1 & 0xFFFF) + (Val2 & 0xFFFF) + (Val3 & 0xFFFF) + (Val4 & 0xFFFF);
   lngOverflow = (long)lngLowWord/65536;
   lngHighWord = ((long)((Val1 & 0xFFFF0000)/65536) + (long)((Val2 & 0xFFFF0000)/65536) + (long)((Val3 & 0xFFFF0000)/65536) + (long)((Val4 & 0xFFFF0000)/65536) + lngOverflow) & 0xFFFF;
   return(UnsignedToLong((lngHighWord*65536) + (lngLowWord & 0xFFFF)));
  }

  private long UnsignedToLong(double Value)
  {
   if(Value<0 || Value>= OFFSET_4)
    throw(new OverflowException());  //抛出溢出的错误

   if(Value<=(double)MAXINT_4)
   {
    return((long)Value);
   }
   else
   {
    return((long)Value - OFFSET_4);
   }
  }

  private double LongTounsigned(long Value)
  {
   if(Value<0)
    return((double)Value + OFFSET_4);
   else
    return((double)Value);
  }

 }
}

原贴作者信息如下,现可以加上我的名字了:)
' Robert Hubley and David Midkiff (mdj2023@hotmail.com)
' modify by simonyan, Support chinese
' modify by 崔恢先(Huixian Cui), Support C#


但是结果不知道为什么,与VB得到的结果并不一样。大家有兴趣帮我看看,我附带了VB的MD5例子,不知道错在哪里。

原创粉丝点击