当前位置: 首页 > 图文教程 > 开发语言 > VC++ > 由汇编内核的MD5算法编写谈代码优化

VC++
在类VC的界面实现中加入目录树
软件换肤技术在 BCB 中的实现
利用非模窗口生成MDI介面
报表输出轻松搞定
Windows 中不规则窗体的编程实现
解说Win32的窗口子类化
使用测试优先方法开发用户界面
一个简单的登录对话框的实现
一个简单的日记本程序
从资源中加载皮肤
一个在RichEdit中添加表情图象的类
ActiveSkin 4.3 软件换肤在VC中的实现
一种另类“关于(About)”对话框的动态显示方法
对话框打印预览及打印
关于如何换肤、子类化的解决方案
制作 MSN、QQ 的消息提示窗口
如何对 BCGControlBarPro 进行换肤
定制个性化的对话框窗口类
改变窗口中的光标形状
更新MFC中的视图,跟踪.NET Framework中的事件

VC++ 中的 由汇编内核的MD5算法编写谈代码优化


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 70 ::
收藏到网摘: n/a

由汇编内核的MD5算法编写谈代码优化
作者:crazyd

下载本文示例工程

去年为了破解动网论坛,写了一个用于破解动网论坛的md5暴力破解程序(http://tongtian.net/pediy/usr/12/12_662.rar),当时为了提高md5算法的运算速度,就将从VCKBASE下载的C代码md5算法改进了一下,结果成效显著。对于代码改写过程中的一些小心得和大家共享,呵呵,高手就不用看了。

开始我们做个实验,先打开两个文档附带的程序,一个工程是MD5C,一个工程是MD5ASM,其中MD5C是从VCKBASE下载的md5算法的标准C语言原代码,MD5ASM是我修改后的md5算法原代码。我给这两个工程的main函数里面都添加了一段回朔代码,用来产生0~99999999的数字,然后用这两个工程里面的可执行文件去对每个数字md5加密。好了,经过一段时间的等待后,就可以看到类似的结果了:

MD5ASM工程在我的机器上的结果是181秒,MD5C在我的机器上产生的结果是999秒,呵呵,数字有点怪,不过我看了表的,差不多是这个时间,巨大的差距是怎样产生的,让我们接下来往下看吧。

在开始正题之前,大家需要清楚一件事,就是MD5C里面的代码虽然效率不高,但绝对是优秀的,因为它主要在演示md5的算法,用的是纯粹的C,没有添加任何平台相干的代码,而我改写的MD5ASM是只能够运行于x86上的windows系统中。所以速度是以兼容性来交换的。

一、算法优化

先观察一下MD5C里面的一段代码:

static void Encode (unsigned char *output, unsigned int *input, unsigned int len){	unsigned int i, j;	for (i = 0, j = 0; j < len; i++, j += 4) {	output[j] = (unsigned char)(input[i] & 0xff);	output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);	output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);	output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);	}}

这是一段将整数数组转换成为字符数组的代码,我们看看它到底做了些什么。假设主函数输入了一个整数0x30313233,那么这个子函数的调用就可以写成下面的样子:
Encode (output, input, 1)
Input指向一个整数数组,数组的第一个元素是0x30313233,我们接下来看函数转换
i=0,j=0output[0]= (unsigned char)(input[0]& 0xff)=0x33output[1]= (unsigned char)(input[0]& 0xff)=0x32output[2]= (unsigned char)(input[0]& 0xff)=0x31output[3]= (unsigned char)(input[0]& 0xff)=0x30i=0,j=4 

跳出循环

output的内存排列顺序为

+--+--+--+--+--
|33|32|31|30|
+--+--+--+--+--
^
output

现在大家注意了,input的排列顺序是什么?由计算机原理可知道,在计算机内部,数据的存放顺序是“高位对应高位,低位对应低位”,0x30313233中的33因为是个位,是低位,所以对应内存单元的最低位,同理30在内存单元的最高位,由此推出0x30313233在数组中的排列顺序为:

+--+--+--+--+--
|33 32 31 30|
+--+--+--+--+--
^
input

结果显而易见了,这个函数的功能只是将一个无符号整形数组转换成为了一个无符号字符形数组,作者的目的我虽然不清楚,但是这个地方确实可以优化如下:

output=(unsigned char *)input;
把这个地方叫作算法的优化可能有点牵强,但是算法的优化确实是最为重要的,比如说搜索算法,如果选择不当,可能要丧失很多的效率。

二、内存拷贝优化

再观察一下MD5C里面的一段代码:
static void MD5_memcpy (unsigned char *output, unsigned int *input, unsigned int len){ unsigned int i; for (i = 0; i < len; i++) output[i] = input[i];}
这处的为什么要修改是非常明显的,for循环是非常慢的,我们一般可以把类似的代码替换成为C的库函数或者操作系统的标准函数,如:
CopyMemory ()memcpy()
这种内存代码你也千万不要尝试自己去实现,那将是一种灾难,在每个操作系统中,内存拷贝可以说是非常频繁的,所以系统的内存拷贝函数基本上都是非常完美的,不信的话你可以自己写一段内存拷贝函数,然后和系统的内