您的位置:首页 > 其它

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

2011-03-09 11:16 399 查看
// 计算数据的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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐