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)); }