MD5加密引出的一段代码
.NET平台的MD5加密做起来很容易,System.Security.Cryptography.MD5进行操作,很容易获得加密之后的字节数组。之所以经常会涉及一些和asp兼容的问题,主要来自于
- System.Security.Cryptography.MD5操作时候,其返回类型是byte[]
- 很多web项目直接使用 System.Web.Security.FormsAuthentication 的 HashPasswordForStoringInConfigFile 方法,这个方法直接返回String类型,大写,所以不兼容。
这引起了我看看ASP.NET到底是怎么实现这个HashPasswordForStoringInConfigFile方法的。看了一下,它的实现,也是先调用了MD5类,然后调用下面的方法,部分源码如下:
static unsafe internal String ByteArrayToHexString(byte[] buf, int iLen)
{
char[] acharval = s_acharval;
if (acharval == null)
{
acharval = new char[16];
for (int i = acharval.Length; --i >= 0; )
{
if (i < 10)
{
acharval[i] = (char)('0' + i);
}
else
{
acharval[i] = (char)('A' + (i - 10));
}
}
s_acharval = acharval;
}
if (buf == null)
return null;
if (iLen == 0)
iLen = buf.Length;
char[] chars = new char[iLen * 2];
fixed (char* fc = chars, fcharval = acharval)
{
fixed (byte* fb = buf)
{
char* pc;
byte* pb;
pc = fc;
pb = fb;
while (--iLen >= 0)
{
*pc++ = fcharval[(*pb & 0xf0) >> 4];
*pc++ = fcharval[*pb & 0x0f];
pb++;
}
}
}
return new String(chars);
}
代码很漂亮,比可以搜索到的一些结果要好很多,这里完整的模拟了2进制转换16进制的方法,每四位变成一位,于是最初代码中创建了一个长度16位的 acharval 字节数组,代表了16进制中的16个表现形式。
由于byte是8为,两个与操作分别取高低8位,进行换算,很好看。
但是这里有了指针不是很理解,未免有点追求华丽的嫌疑,因为我用CodeTimer(thanks to @jeffz_cn) 的测试结果表明,不用指针,仅仅是foreach循环,算法一样的话,两种实现方式性能相差无几。
测试代码:
private static void ToStringWithoutPointer(byte[] buf)
{
int iLen = buf.Length;
char[] chars = new char[iLen * 2];
int index = 0;
foreach (var item in buf)
{
chars[index++] = acharval[(item & 0xf0) >> 4];
chars[index++] = acharval[item & 0x0f];
}
//Console.WriteLine(new String(chars));
}
浙公网安备 33010602011771号