计算MD5的小程序源代码

常常需要计算文件的MD5。到网上一搜,发现有的MD5计算程序还不是免费的。那还不如自己动手写一个。用Windows API,要不了多少代码。下面给出我写的小程序的完整源代码:

 

/*

 * md5.c

 * Calc file's MD5 hash value by WIN32 crypto API.

 

 * Version: 1.00.00

 

 * Copyright (c) 2010, Wang Xiaojian <[email protected]>,

 * Bit R&D Studio. All rights reserved.

 

 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND

 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE

 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS

 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT

 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY

 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF

 * SUCH DAMAGE.

 */

 

#include <windows.h>

#include <tchar.h>

#pragma comment(lib,"crypt32")

 

// 把文件中的所有数据读取到缓冲区中

// 应用程序负责在适当的时候用free释放缓冲区

__inline BOOL LoadFile(LPCTSTR pszFile,LPBLOB pBlob)

{

     HANDLE hFile =CreateFile(pszFile,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);

     if(INVALID_HANDLE_VALUE==hFile)

         return FALSE;

     pBlob->cbSize =GetFileSize(hFile,NULL);

     if(pBlob->cbSize!=0)

     {

         pBlob->pBlobData =(LPBYTE)malloc(pBlob->cbSize);

         if(pBlob->pBlobData!=NULL)

         {

              if(!ReadFile(hFile,pBlob->pBlobData,pBlob->cbSize,&pBlob->cbSize,NULL))

              {

                   free(pBlob->pBlobData);

                   pBlob->pBlobData =NULL;

                   pBlob->cbSize =0;

              }

         }

     }

     CloseHandle(hFile);

     return (pBlob->pBlobData!=NULL);

}

 

// 封装CryptAcquireContext函数

__inline BOOL AcquireContext(HCRYPTPROV* phProv)

{

     return (CryptAcquireContext(phProv,NULL,MS_STRONG_PROV,PROV_RSA_FULL,0) ||

         CryptAcquireContext(phProv,NULL,MS_STRONG_PROV,PROV_RSA_FULL,CRYPT_NEWKEYSET));

}

 

// 计算二进制数据的MD5

// 参数说明:

// pData      [in] 指向包含待计算MD5的二进制数据的缓冲区地址

// cbData     [in] 二进制数据长度,以字节为单位

// pHashData  [out, size_is(cbMaxSize)] 指向接收MD5的缓冲区地址

// cbMaxSize  [in] 接收MD5的缓冲区长度,以字节为单位

// 返回值:

// 填充pHashData的数据长度,以字节为单位

DWORD GetMD5(const void* pData,DWORD cbData,PBYTE pHashData,DWORD cbMaxSize)

{

     HCRYPTPROV hProv;

     HCRYPTHASH hHash;

     DWORD cb=0,cbSize =cbMaxSize;

     if(AcquireContext(&hProv))

     {

         if(CryptCreateHash(hProv,CALG_MD5,0,0,&hHash))

         {

              if(CryptHashData(hHash,pData,cbData,0))

              {

                   if(CryptGetHashParam(hHash,HP_HASHVAL,pHashData,&cbSize,0))

                   {

                       cb =cbSize;

                   }

              }

              CryptDestroyHash(hHash);

         }

         CryptReleaseContext(hProv,0);

     }

     return cb;

}

 

// 计算文件MD5

// 参数说明:

// pszFile    [in, string] 指向包含待计算MD5的文件路径字符串的缓冲区地址

void ShowMD5(LPCTSTR pszFile)

{

     BLOB blob;

     BYTE pHashData[32];

     DWORD cbHash,cbSize =sizeof(pHashData);

     TCHAR szText[MAX_PATH];

     DWORD cb =MAX_PATH;

     if(!LoadFile(pszFile,&blob))

         return;

     cbHash =GetMD5(blob.pBlobData,blob.cbSize,pHashData,cbSize);

     if(cb!=0)

     {

         if(CryptBinaryToString(pHashData,cbHash,CRYPT_STRING_HEX,szText,&cb))

         {

              MessageBox(NULL,szText,pszFile,MB_OK);

         }

     }

     free(blob.pBlobData);

}

 

int APIENTRY _tWinMain(HINSTANCE hInstance,

      HINSTANCE hPrevInstance,

      LPTSTR    lpCmdLine,

      int       nCmdShow)

{

     hInstance;

     hPrevInstance;

     nCmdShow;

     if(0==*lpCmdLine)

     {

         TCHAR szFile[MAX_PATH];

         OPENFILENAME ofn ={sizeof(OPENFILENAME)};

         *szFile =0;

         ofn.hwndOwner =NULL;

         ofn.lpstrFile =szFile;

         ofn.nMaxFile =MAX_PATH;

         ofn.Flags =OFN_NONETWORKBUTTON|OFN_FILEMUSTEXIST;

         if(!GetOpenFileName(&ofn))

              return -1;

         ShowMD5(szFile);

     }

     else

     {

         if(0xFFFFFFFF==GetFileAttributes(lpCmdLine))

              return -1;

         ShowMD5(lpCmdLine);

     }

     return 0;

}

 

你可能感兴趣的:(windows,String,File,null,express,Path)