首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VB >

【源码】VB6.0 调用Windows系统的API计算MD5码解决方法

2013-10-19 
【源码】VB6.0 调用Windows系统的API计算MD5码前几天,有网友发贴,求一个非对称加密的VB算法代码。  当时自然

【源码】VB6.0 调用Windows系统的API计算MD5码
前几天,有网友发贴,求一个非对称加密的VB算法代码。
  当时自然就想到了RSA加密算法。本想在系统中找RSA加密算法的API,却没找到。
  在网上搜索算法代码,几乎就是找到一些千篇一律的“理论介绍”,C/C++代码倒是有一些,但我还没有试验效
果如何。费了很大的劲翻出的VB代码,一试,结果根本不行……

  RSA的没什么收获,但却意外的找到了MD5的函数库。

  当然,你也许会说,MD5的算法代码,网上一堆堆的,多的是…………
  这个我也不否认。网上一出来点好东西,往往就会你抄我、他抄你的,不管看没看懂、不管有没有什么问题,只
管 Copy & Paste 。内容千篇一律,有的还说明“出处”,有的干脆就“据为已出”!如果“源头”有什么错误,
后面的基本都是跟着错的。
  对此放下不谈,再说下这些源码问题。这些MD5计算的源码,不管是C/C++的也好,还是VB的也好,或者是其它语
言的,都是把具体计算过程,用代码实现了的。那个代码模块,无论他是否进行过“封装”,面临的也是一大堆的代
码、十几个甚至近20个的函数。VB6.0的代码,就拿网上比较流行的版本来说吧,整个模块约12K代码(什么注释也不
要写),全部函数约20个。这里面不少的函数就几行代码而已,但有几个主要过程的代码是极长的。如果把这个模块
加入自己的工程代码中,在自己的工程代码编写或维护过程中,万一不小心把哪改动了一点,或不小心删除了某行,
那问题就大了,要找起来那可是累死人(当然也可以用备份的模块来全部还原)。再者,在VB6中,不支持移位运算,
整数是带符号的,运算中还可能有“溢出”问题。移位运算是用算术运算来“模拟”的,效率自然低了很多。 还有
就是算法过程,基本上就是第一个人出来之后,代码过程就是那样了,代码质量基本就是取决于“第一人”的编写水
平,即使这里面有需要优化的地方,也基本上没人去改它。一大堆的代码,写得很不规范,看着都晕……

  相比之下,我这个用系统API来计算MD5码的模块,就比较有优越性了。
  ① 代码量少,维护容易。我这个模块,如果去掉全部注释,不足3KB了。
      (并且基本上没什么“优化”的必要了,我自认为写得还不错! ^_^)
  ② 不用担心算法出错,或不能使用。
    ⑴微软的Windows系统自己在用,这个无论哪个版本的Windows系统,都会有这个库的。
    ⑵具体的核心计算过程是系统API实现的,不用担心有错:其一,他不能有错,系统中有那么多的证书,需
  要进行MD5验证的,算法有错会出问题。其二,那些证书,不少是经过权威机构“公证”过的,你想下,微软的
  这个算法库,它能够有错吗?它敢有错吗???

  好了,别的不扯了,上代码:
(下面这段是在一个标准模块中的代码)

'        ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
'        ::::::::::::::::::::::::::::::::::::::::::::::::::::::::
'        :::::                                              :::::
'        :::::         使用 Windows API 来计算 MD5          :::::
'        :::::                                              :::::
'        ::::::::::::::::::::::::::::::::::::::::::::::::::::::::
'        ````````````````````````````````````````````````````````
'
'  * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
'           -=  函 数 清 单  =-
'     GetMD5Text        获取上次计算的MD5码文本
'     MD5Bytes          计算一个字节数组的MD5码
'     MD5String         计算一个字符串(ANSI编码)的MD5码
'     MD5File           计算一个文件的MD5码
'  * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
'
Option Explicit

' ==============================
' ≡     自定义 数据类型      ≡
' ==============================
Type MD5_CTX
      dwNUMa      As Long
      dwNUMb      As Long
      Buffer(15)  As Byte
      cIN(63)     As Byte
      cDig(15)    As Byte
End Type

' ==============================
' ≡     API 函 数 声 明      ≡
' ==============================
Private Declare Sub MD5Init Lib "advapi32" (lpContext As MD5_CTX)
Private Declare Sub MD5Final Lib "advapi32" (lpContext As MD5_CTX)
Private Declare Sub MD5Update Lib "advapi32" (lpContext As MD5_CTX, _
                           ByRef lpBuffer As Any, ByVal BufSize As Long)

Private stcContext   As MD5_CTX


' ==============================
' ≡     通用 函数 & 过程     ≡
' ==============================
' * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
' 功    能:计算一个字符串(ANSI编码)的MD5码
' 入口参数:
'  strText     字符串文本
' 返回参数:   MD5码 (16字节的Byte数组)


' * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Public Function MD5String(strText As String) As Byte()
      Dim aBuffer()     As Byte

   Call MD5Init(stcContext)
   If (Len(strText) > 0) Then
      aBuffer = StrConv(strText, vbFromUnicode)
      Call MD5Update(stcContext, aBuffer(0), UBound(aBuffer) + 1)
   Else
      Call MD5Update(stcContext, 0, 0)
   End If
   Call MD5Final(stcContext)
   MD5String = stcContext.cDig
End Function

' * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
' 功    能:计算一个字节流的MD5码
' 入口参数:
'  Buffer      Byte数组
'  size        长度(可选,默认计算整个长度)
' 返回参数:   MD5码 (16字节的Byte数组)
' * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Public Function MD5Bytes(Buffer() As Byte, _
                        Optional ByVal size As Long = -1) As Byte()
      Dim U As Long, pBase   As Long

   pBase = LBound(Buffer)
   U = UBound(Buffer) - pBase
   If (-1 = size) Then size = U + 1
   Call MD5Init(stcContext)
   If (-1 = U) Then
      Call MD5Update(stcContext, 0, 0)
   Else
      Call MD5Update(stcContext, Buffer(pBase), size)
   End If
   Call MD5Final(stcContext)
   MD5Bytes = stcContext.cDig
End Function

' * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
' 功    能:计算一个文件的MD5码
' 入口参数:
'  FileName    磁盘文件名(完整路径)
' 返回参数:   MD5码 (16字节的Byte数组)
' * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Public Function MD5File(ByVal FileName As String) As Byte()
   Const BUFFERSIZE  As Long = 1024& * 512      ' 缓冲区 512KB
      Dim DataBuff() As Byte
      Dim lFileSize  As Long
      Dim iFn        As Long

   On Error GoTo E_Handle_MD5
   If (Len(Dir$(FileName)) = 0) Then Err.Raise 5      '文件不存在
   ReDim DataBuff(BUFFERSIZE - 1)
   iFn = FreeFile()
   Open FileName For Binary As #iFn
   lFileSize = LOF(iFn)
   Call MD5Init(stcContext)
   If (lFileSize = 0) Then
      Call MD5Update(stcContext, 0, 0)
   Else
      Do While (lFileSize > 0)
         Get iFn, , DataBuff
         If (lFileSize > BUFFERSIZE) Then
            Call MD5Update(stcContext, DataBuff(0), BUFFERSIZE)
         Else
            Call MD5Update(stcContext, DataBuff(0), lFileSize)
         End If
         lFileSize = lFileSize - BUFFERSIZE
      Loop
   End If
   Close iFn
   Call MD5Final(stcContext)
E_Handle_MD5:
   MD5File = stcContext.cDig


End Function

' * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
' 功    能:获取上次计算的MD5码文本
' 入口参数:   < 无 >
' 返回参数:   MD5码文本字符串(没有MD5数据 返回空串)
' * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Public Function GetMD5Text() As String
      Dim sResult As String, i&
   If (stcContext.dwNUMa = 0) Then
      sResult = vbNullString
   Else
      sResult = Space$(32)
      For i = 0 To 15
         Mid$(sResult, i + i + 1) = Right$("0" & Hex$(stcContext.cDig(i)), 2)
      Next
   End If
   GetMD5Text = sResult       ' LCase$(sResult) '字母小写
End Function



(下面这段是应用示例。在一个窗体模块中)

[解决办法]
   顶一下      顶一下
[解决办法]
支持一下【源码】VB6.0 调用Windows系统的API计算MD5码解决方法
[解决办法]
虽然不知道大家在说些什么,但貌似很厉害的样子。
[解决办法]
支持一下支持一下
[解决办法]
感谢楼主分享【源码】VB6.0 调用Windows系统的API计算MD5码解决方法
[解决办法]
看不懂/////
[解决办法]
learning
[解决办法]
你去算一下效率,看看哪个要多久,比方一次要几毫秒,,计算一万次要多久,然后看下哪个效率高
[解决办法]
支持一下支持一下....
[解决办法]
感谢楼主分享
[解决办法]
【源码】VB6.0 调用Windows系统的API计算MD5码解决方法
[解决办法]
看看是什么~
[解决办法]
学习了,谢谢,辛苦
[解决办法]
叼炸天【源码】VB6.0 调用Windows系统的API计算MD5码解决方法
[解决办法]
学习了,顶一个
[解决办法]
好像很高级的样子、
[解决办法]

好好看看 顶 顶 顶


[解决办法]
貌似很厉害啊
[解决办法]
多快好省的法子,支持分享。
[解决办法]
谢谢分享 哈哈哈
[解决办法]
很好,谢谢。下载了,找机会加到工程中去。
[解决办法]
十几年了,还有人用VB?
[解决办法]
这东西好啊 12345567
[解决办法]
支持下.........
[解决办法]
貌似很厉害啊
[解决办法]
支持,学习一下
[解决办法]
这个不错,不用挂个md5模块了
[解决办法]
wa【源码】VB6.0 调用Windows系统的API计算MD5码解决方法
[解决办法]
原来是这样 谢谢、
[解决办法]

asdas
[解决办法]
就这样被你征服。。
[解决办法]
谢谢了。。。。就这样被你征服
[解决办法]
支持下.........
[解决办法]
非常好,感谢分享
[解决办法]
欢迎大家发表见解!
[解决办法]
MD5的全称是Message-Digest Algorithm 5,在90年代初由MIT的计算机科学实验室和RSA Data Security Inc发明,经MD2、MD3和MD4发展而来。 
Message-Digest泛指字节串(Message)的Hash变换,就是把一个任意长度的字节串变换成一定长的大整数。请注意我使用了“字节串”而不是“字符串”这个词,是因为这种变换只与字节的值有关,与字符集或编码方式无关。 
MD5将任意长度的“字节串”变换成一个128bit的大整数,并且它是一个不可逆的字符串变换算法,换句话说就是,即使你看到源程序和算法描述,也无法将一个MD5的值变换回原始的字符串,从数学原理上说,是因为原始的字符串有无穷多个,这有点象不存在反函数的数学函数。 
MD5的典型应用是对一段Message(字节串)产生fingerprint(指纹),以防止被“篡改”。举个例子,你将一段话写在一个叫 readme.txt文件中,并对这个readme.txt产生一个MD5的值并记录在案,然后你可以传播这个文件给别人,别人如果修改了文件中的任何内容,你对这个文件重新计算MD5时就会发现(两个MD5值不相同)。如果再有一个第三方的认证机构,用MD5还可以防止文件作者的“抵赖”,这就是所谓的数字签名应用。 
MD5还广泛用于加密和解密技术上,在很多操作系统中,用户的密码是以MD5值(或类似的其它算法)的方式保存的, 用户Login的时候,系统是把用户输入的密码计算成MD5值,然后再去和系统中保存的MD5值进行比较,而系统并不“知道”用户的密码是什么。

[解决办法]
对于中文就有些不同:

MD5("中秋快乐!") = 83C84C1D18B951A651236C48AA2FD9F0

http://blog.csdn.net/a814153a/article/details/9211793
MD5("中秋快乐!") = 9653a645c0a81fd78251fd99a83dd8ac

[解决办法]
http://www.supfree.net/search.asp?id=6223
http://blog.csdn.net/a814153a/article/details/9211793
三种方法中文都不一样。
[解决办法]

[解决办法]
en【源码】VB6.0 调用Windows系统的API计算MD5码解决方法【源码】VB6.0 调用Windows系统的API计算MD5码解决方法
[解决办法]
方法
[解决办法]
方法


分享真好
[解决办法]
引用:
Quote: 引用:


Quote: 引用:

感谢楼主分享【源码】VB6.0 调用Windows系统的API计算MD5码解决方法
方法


分享真好


未设定 空间
[解决办法]
。。。。我只会E语言
[解决办法]
辛苦了,,,,,,,,,,,
[解决办法]
感谢楼主,很好很强。佩服。
[解决办法]
看看是什么~
[解决办法]
【源码】VB6.0 调用Windows系统的API计算MD5码解决方法
[解决办法]
测试一致,证明楼主的判断:把含中文的字符串转换成UTF-8编码的字节数组,再调用字节流函数。
[解决办法]
来学习学习.路过
[解决办法]
支持分享!收藏下,以备后用!
[解决办法]
【源码】VB6.0 调用Windows系统的API计算MD5码解决方法
[解决办法]
不明觉厉。99楼

热点排行