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例子,不知道错在哪里。