惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

阮一峰的网络日志
阮一峰的网络日志
D
Darknet – Hacking Tools, Hacker News & Cyber Security
S
Schneier on Security
The Last Watchdog
The Last Watchdog
Cyberwarzone
Cyberwarzone
S
Securelist
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Cyber Attacks, Cyber Crime and Cyber Security
L
Lohrmann on Cybersecurity
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 司徒正美
The Cloudflare Blog
V
V2EX
博客园_首页
博客园 - 聂微东
Vercel News
Vercel News
人人都是产品经理
人人都是产品经理
G
GRAHAM CLULEY
T
Tenable Blog
Last Week in AI
Last Week in AI
Y
Y Combinator Blog
L
LINUX DO - 最新话题
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
SecWiki News
SecWiki News
博客园 - 三生石上(FineUI控件)
S
Secure Thoughts
N
News | PayPal Newsroom
T
The Blog of Author Tim Ferriss
The GitHub Blog
The GitHub Blog
T
Troy Hunt's Blog
博客园 - 【当耐特】
Forbes - Security
Forbes - Security
H
Hacker News: Front Page
A
About on SuperTechFans
B
Blog RSS Feed
Engineering at Meta
Engineering at Meta
MongoDB | Blog
MongoDB | Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
罗磊的独立博客
D
DataBreaches.Net
P
Privacy & Cybersecurity Law Blog
Schneier on Security
Schneier on Security
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Google DeepMind News
Google DeepMind News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Jina AI
Jina AI
D
Docker
P
Proofpoint News Feed

博客园 - 老三

“内部开源” 视野,自学,和其他 反编译yield未解决问题记录 编译,调试mono运行时 确实,是有学习曲线的 mono 的Sgen mono 执行顺序 UTF8编码 *nix mono 找不到 MySql.Data Could not be loaded *nix,mono运行reflector 【翻译】正确的精神 11期Beta技术沙龙总结体会 记一次Cookie调试 Hubble.net Maillist 【译文】版本一很糟,但也坚持发布 《重构》读书体会以及近期相关工作 NHibernate no session or session was closed问题以及NH最佳实践 推荐the productive programmer Vim 还是 Emacs
MD5加密引出的一段代码
老三 · 2010-04-12 · via 博客园 - 老三

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