日期:2008-10-10 浏览次数:21011 次
在.net中,由于.net framework 封装了常见的加密算法,因此实现标准的MD5算法只需要短短几行代码即可实现:
public string Md5(string strPassword)
{
MD5CryptoServiceProvider hashmd5;
hashmd5 = new MD5CryptoServiceProvider();
return BitConverter.ToString(hashmd5.ComputeHash(Encoding.Default.GetBytes(strPassword))).Replace("-","").ToLower();
}
,但是当加密字符串含有中文或者其它双字节字符时,这种算法的结果与目前网上流行的ASP写的MD5算法的结果却不一致,这主要是由于目前网上流行的ASP写的MD5加密算法,存在一个缺陷,它使用了mid函数,取出的是“字符”,而正确的做法应该是取出字节,因此当加密字符串有双字节字符时,结果会与标准的MD5算法不一致.。但是由于在ASP向ASP.net的系统进行升级的过程中,已经向数据库内写入了大量以前ASP算法加密的密码,为了使新系统能够与原来的系统完全兼容,因此只有在.net 环境下实现与原来ASP算法完全一致的MD5算法。我的实现思路如下:
1、先用正则表达式对要加密的字符串进行判断,是否含有双字节字符。
2、如果含有双字节字符,调用实现与ASP算法一致的非托管COM组件进行处理。(这个组件只需要将原ASP加密算法代码进行适当修改,然后加入VB6中进行编译即可得到)。
3、否则直接调用.net的标准MD5加密算法。
可能有的朋友会问到,为什么不都直接调用COM组件来加密呢?这主要是从性能角度考虑的,由于调用非托管COM组件,.net需要生成一个代理类与之交互,所以在性能方面要远远低于.net内置的函数。
下面给出所有代码:
原ASP加密代码:
<%
Private Const BITS_TO_A_BYTE = 8
Private Const BYTES_TO_A_WORD = 4
Private Const BITS_TO_A_WORD = 32
Private m_lOnBits(30)
Private m_l2Power(30)
m_lOnBits(0) = CLng(1)
m_lOnBits(1) = CLng(3)
m_lOnBits(2) = CLng(7)
m_lOnBits(3) = CLng(15)
m_lOnBits(4) = CLng(31)
m_lOnBits(5) = CLng(63)
m_lOnBits(6) = CLng(127)
m_lOnBits(7) = CLng(255)
m_lOnBits(8) = CLng(511)
m_lOnBits(9) = CLng(1023)
m_lOnBits(10) = CLng(2047)
m_lOnBits(11) = CLng(4095)
m_lOnBits(12) = CLng(8191)
m_lOnBits(13) = CLng(16383)
m_lOnBits(14) = CLng(32767)
m_lOnBits(15) = CLng(65535)
m_lOnBits(16) = CLng(131071)
m_lOnBits(17) = CLng(262143)
m_lOnBits(18) = CLng(524287)
m_lOnBits(19) = CLng(1048575)
m_lOnBits(20) = CLng(2097151)
m_lOnBits(21) = CLng(4194303)
m_lOnBits(22) = CLng(8388607)
m_lOnBits(23) = CLng(16777215)
m_lOnBits(24) = CLng(33554431)
m_lOnBits(25) = CLng(67108863)
m_lOnBits(26) = CLng(134217727)
m_lOnBits(27) = CLng(268435455)
m_lOnBits(28) = CLng(536870911)
m_lOnBits(29) = CLng(1073741823)
m_lOnBits(30) = CLng(2147483647)
m_l2Power(0) = CLng(1)
m_l2Power(1) = CLng(2)
m_l2Power(2) = CLng(4)
m_l2Power(3) = CLng(8)
m_l2Power(4) = CLng(16)
m_l2Power(5) = CLng(32)
m_l2Power(6) = CLng(64)
m_l2Power(7) = CLng(128)
m_l2Power(8) = CLng(256)
m_l2Power(9) = CLng(512)
m_l2Power(10) = CLng(1024)
m_l2Power(11) = CLng(2048)
m_l2Power(12) = CLng(4096)
m_l2Power(13) = CLng(8192)
m_l2Power(14) = CLng(16384)
m_l2Power(15) = CLng(32768)
m_l2Power(16) = CLng(65536)
m_l2Power(17) = CLng(131072)
m_l2Power(18) = CLng(262144)
m_l2Power(19) = CLng(524288)
m_l2Power(20) = CLng(1048576)
m_l2Power(21) = CLng(2097152)
m_l2Power(22) = CLng(4194304)
m_l2Power(23) = CLng(8388608)
m_l2Power(24) = CLng(16777216)
m_l2Power(25) = CLng(33554432)
m_l2Power(26) = CLng(67108864)
m_l2Power(27) = CLng(134217728)
m_l2Power(28) = CLng(268435456)
m_l2Power(29) = CLng(536870912)
m_l2Power(30) = CLng(1073741824)
Private Function LShift(lValue, iShiftBits)
If iShiftBits = 0 Then
LShift = lValue
Exit Function
ElseIf iShiftBits = 31 Then
If lValue And 1 Then
LShift = &H80000000
Else
LShift = 0
End If
Exit Function
ElseIf iShiftBits < 0 Or iShiftBits > 31 Then
Err.Raise 6
End If
If (lValue And m_l2Power(31 - iShiftBits)) Then
LShift = ((lValue And m_lOnBits(31 - (iShiftBits + 1))) * m_l2Power(iShiftBits)) Or &H80000000
Else
LShift = ((lValue And m_lOnBits(31 - iShiftBits)) * m_l2Power(iShiftBits))