现在的位置: 首页 > 综合 > 正文

MD5加密引出的一段代码

2012年10月03日 ⁄ 综合 ⁄ 共 1376字 ⁄ 字号 评论关闭

.NET平台的MD5加密做起来很容易,System.Security.Cryptography.MD5进行操作,很容易获得加密之后的字节数组。之所以经常会涉及一些和asp兼容的问题,主要来自于

  1. System.Security.Cryptography.MD5操作时候,其返回类型是byte[]
  2. 很多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));
        }

抱歉!评论已关闭.