使用Windows系统API计算数据和文件的MD5哈希值,支持大文件

来源:互联网 发布:用单片机产生正弦波 编辑:程序博客网 时间:2024/06/05 00:51
// 计算数据的MD5字符串
string ComputeMD5(const char* szData, size_t len){HCRYPTPROV hCryptProv;HCRYPTHASH hHash;BYTE bHash[0x7f];DWORD dwHashLen= 16;string digest; if(CryptAcquireContext(&hCryptProv,NULL, NULL, PROV_RSA_FULL,CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET) &&CryptCreateHash(hCryptProv,CALG_MD5,0, 0, &hHash) &&CryptHashData(hHash, (BYTE*)szData, (DWORD)len, 0) &&CryptGetHashParam(hHash, HP_HASHVAL, bHash, &dwHashLen, 0)){digest.resize(32);BYTE value;for (int i = 0; i<16; i++){value = bHash[i] >> 4;digest[i*2] = value < 10 ? char(value + '0') : char(value - 10 + 'a');value = bHash[i] & 0x0F;digest[i*2+1] = value < 10 ? char(value + '0') : char(value - 10 + 'a');}} CryptDestroyHash(hHash);CryptReleaseContext(hCryptProv, 0);return digest;}
// 计算文件的MD5字符串,支持大文件(large file)
string ComputeFileMD5(const TCHAR* szFilename){HCRYPTPROV hCryptProv = 0;HCRYPTHASH hHash = 0;HANDLE hMapFile = 0; BYTE bHash[0x7f];DWORD dwHashLen= 16;BYTE* pBuf;string digest;DWORD dwFileSize = 0, dwHighFileSize = 0; HANDLE hFile = CreateFile(szFilename, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);if( hFile == INVALID_HANDLE_VALUE ){return digest;} dwFileSize = GetFileSize(hFile, &dwHighFileSize); hMapFile = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); if (hMapFile == NULL || hMapFile == INVALID_HANDLE_VALUE){goto release;} if(CryptAcquireContext(&hCryptProv,NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)){if(CryptCreateHash(hCryptProv,CALG_MD5,0, 0, &hHash)){UINT64 filesize = (UINT64)dwHighFileSize << 32 | dwFileSize;for(UINT64 i = 0; i <= filesize; i+=1048576)// 1024*1024{size_t bufsize = size_t(min(filesize-i, 1048576));pBuf = (BYTE*) MapViewOfFile(hMapFile, FILE_MAP_READ, (DWORD)(i >> 32), (DWORD)i, bufsize); if (pBuf == NULL){goto release;} if(!CryptHashData(hHash, pBuf, bufsize, 0)){goto release;}UnmapViewOfFile(pBuf);}if(CryptGetHashParam(hHash, HP_HASHVAL, bHash, &dwHashLen, 0)){digest.resize(32);BYTE value;for (int i = 0; i<16; i++){value = bHash[i] >> 4;digest[i*2] = value < 10 ? char(value + '0') : char(value - 10 + 'a');value = bHash[i] & 0x0F;digest[i*2+1] = value < 10 ? char(value + '0') : char(value - 10 + 'a');}}}} release:CryptDestroyHash(hHash);CryptReleaseContext(hCryptProv, 0);UnmapViewOfFile(pBuf);CloseHandle(hMapFile);CloseHandle(hFile);return digest;}
原创粉丝点击