看來需要用這個才是關鍵的處理。利用SHA1 源碼來處理超大檔案的checksum值計算真的好慢。
改用:Windows Crypt API。先嘗試一下看不看快起來。
If you happen to be developing your code to be Microsoft Windows
specific, the Windows Cryptographic Library contains the MD5 and SHA-1
hash functions. Microsoft provides functions called CryptCreateHash
,
CryptHashData
,
CryptGetHashParam
and CryptDestroyHash
which can be used to run the MD5 or SHA-1 hash functions on given
message data to produce a message digest.
The use of these functions is pretty simple. First, as with most
Windows cryptography operations, you need to create a Crypt Context
using the CryptAcquireContext
function. Once the context is acquired, you must create a hash object
using the CryptCreateHash
function. This hash object will hold the state of your hash function
and will also hold the result when complete. When you call CryptCreateHash
,
you must specify which hash function you want. You can choose between
several hash functions: CALG_MD2, CALG_MD4, CALG_MD5, CALG_SHA1,
CALG_SHA_256, CALG_SHA_384 and CALG_SHA_512. Each of these
cryptographic hash algorithms can have different message digest lengths.
Once the hash object is created, you must call the CryptHashData
function. This function is used to pass the message data into the
cryptographic hash function. This function can be called multiple
times to keep feeding message data into the function. This is helpful if
you are reading data from a file or other stream. Once you are done
feeding data to the function, you need to retrieve the message digest
from the hash object. You do this using the CryptGetHashParam
function. This function will be called twice. Once for retrieving the
length of the digest (HP_HASHSIZE) and again for retrieving the digest
itself (HP_HASHVAL). Once you have the message digest, you can destroy
the hash object and the crypt context using the CryptDestroyHash
and CryptReleaseContext
functions respectively.
#include <Windows.h><br />#include <WinCrypt.h><br />#include <stdio.h><br />// NOTE: In the interest of keeping the example short, I omitted error code checking.<br />// Please make sure you add error code checking to your applications.<br />int wmain(int argc, wchar_t * argv[])<br />{<br />HCRYPTPROVhCryptProv = NULL;<br />HCRYPTHASHhCryptHash = NULL;<br />if ( argc < 2 )<br />{<br />printf("Usage: %s <filename>/n", argv[0]);<br />return 2;<br />}<br />CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0);<br />CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hCryptHash);<br />HANDLE hInputFile = CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);<br />if ( hInputFile == INVALID_HANDLE_VALUE )<br />{<br />printf("Error: Unable to open file /"%s/" (0x%X)/n", argv[1], ::GetLastError());<br />return 2;<br />}<br />BYTE * dataBuffer = new BYTE[16384];<br />DWORD bytesRead = 0;<br />while (ReadFile(hInputFile, dataBuffer, 16384, &bytesRead, NULL))<br />{<br />if ( bytesRead == 0 )<br />break;<br />CryptHashData(hCryptHash, dataBuffer, bytesRead, 0);<br />}<br />CloseHandle(hInputFile);<br />delete [] dataBuffer;<br />DWORD hashLength = 0;<br />DWORD hashLengthLength = sizeof(DWORD);<br />CryptGetHashParam(hCryptHash, HP_HASHSIZE, (BYTE *) &hashLength, &hashLengthLength, 0);<br />BYTE *hashDigest = new BYTE[hashLength];<br />DWORD hashDigestLength = hashLength;<br />CryptGetHashParam(hCryptHash, HP_HASHVAL, hashDigest, &hashDigestLength, 0);<br />if(hCryptHash)<br />CryptDestroyHash(hCryptHash);<br />if(hCryptProv)<br />CryptReleaseContext(hCryptProv,0);<br />for ( size_t i = 0; i < hashLength; i++ )<br />printf("%02x", hashDigest[i]);<br />printf("/n");<br />delete [] hashDigest;<br />return 0;<br />}<br />
參考:http://www.tomhandal.com/DevBlog/2010/06/13/md5sha-1-cryptographic-hash-functions-in-windows/
http://blog.csdn.net/dkfdtf/archive/2009/03/14/3989388.aspx