使用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;
}
相关文章推荐
- Oracle 数据文件 实际使用量 计算说明
- Oracle 数据文件 实际使用量 计算说明
- Oracle 数据文件 实际使用量 计算说明
- Oracle 数据文件 实际使用量 计算说明
- (打渔晒网)使用文件输入数据 将计算结果储存到另一文件中
- [大数据]连载No2之Hadoop文件增删改查API使用
- net控件中数据导到Excel的格式 首先,我们了解一下excel从web页面上导出的原理。当我们把这些数据发送到客户端时,我们想让客户端程序(浏览器)以excel的格式读取它,所以把mime类型设为:application/vnd.ms-excel,当excel读取文件时会以每个cell的格式呈现数据,如果cell没有规定的格式,则excel会以默认的格式去呈现该cell的数据。这样就给我们提供了自定义数据格式的空间,当然我们必须使用excel支持的格式。下面就列出常用的一些格式: 1) 文本
- Oracle 数据文件 实际使用量 计算说明
- 本人写的如何使用DFS API 合并为一个大的天气数据文件
- 使用安捷伦波形编辑软件产生GK101 任意波数据文件的方法(支持手绘)
- Oracle 数据文件 实际使用量 计算说明
- 使用webrtc中的MD5 API计算某个文件的MD5值
- 某些输入文件使用或覆盖了已过时的 API
- Android 音视频开发(四):使用 Camera API 采集视频数据
- android使用webview上传文件(支持相册和拍照)
- 使用dom4j读取xml文件初始化数据
- 使用SQL语句创建SQL数据脚本(应对万网主机部分不支持导出备份数据)
- android--内部存储写文件和使用API获取内部存储路径,sharedperferance获取原有的账号密码--简单的登陆(记录原有的账号和密码)--I/0流介绍
- [ATL/WTL]_[初级]_[如何使用GetOpenFileName多选文件-根据文件名长度计算lpstrFile长度]
- linux系统误删文件怎么办!使用extundelete恢复数据