发现一个很奇怪的现象:
python语言求哈希值所用时间竟然比C++少:
C++ code
1 #include "stdafx.h" 2 #include <windows.h> 3 #include <time.h> 4 #include <iostream> 5 void ShowError(char *pszText) 6 { 7 char szErr[MAX_PATH] = { 0 }; 8 ::sprintf_s(szErr, "%s Error[%d] ", pszText, ::GetLastError()); 9 #ifdef _DEBUG 10 // required size 11 int size = MultiByteToWideChar(CP_UTF8, 0, szErr, -1, NULL, 0); 12 wchar_t *pwcsName = new wchar_t[size]; 13 MultiByteToWideChar(CP_UTF8, 0, szErr, -1, (LPWSTR)pwcsName, size); 14 ::MessageBox(NULL, pwcsName, L"ERROR", MB_OK | MB_ICONERROR); 15 delete[] pwcsName; 16 #endif 17 } 18 19 20 BOOL GetFileData(char *pszFilePath, BYTE **ppFileData, DWORD *pdwFileDataLength) 21 { 22 BOOL bRet = TRUE; 23 BYTE *pFileData = NULL; 24 DWORD dwFileDataLength = 0; 25 HANDLE hFile = NULL; 26 DWORD dwTemp = 0; 27 28 do 29 { 30 // required size 31 int size = MultiByteToWideChar(CP_UTF8, 0, pszFilePath, -1, NULL, 0); 32 wchar_t *pwcsName = new wchar_t[size]; 33 MultiByteToWideChar(CP_UTF8, 0, pszFilePath, -1, (LPWSTR)pwcsName, size); 34 hFile = ::CreateFile(pwcsName, GENERIC_READ | GENERIC_WRITE, 35 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 36 FILE_ATTRIBUTE_ARCHIVE, NULL); 37 delete[] pwcsName; 38 if (INVALID_HANDLE_VALUE == hFile) 39 { 40 bRet = FALSE; 41 ShowError("CreateFile"); 42 break; 43 } 44 45 dwFileDataLength = ::GetFileSize(hFile, NULL); 46 47 pFileData = new BYTE[dwFileDataLength]; 48 if (NULL == pFileData) 49 { 50 bRet = FALSE; 51 ShowError("new"); 52 break; 53 } 54 ::RtlZeroMemory(pFileData, dwFileDataLength); 55 56 ::ReadFile(hFile, pFileData, dwFileDataLength, &dwTemp, NULL); 57 58 // 返回 59 *ppFileData = pFileData; 60 *pdwFileDataLength = dwFileDataLength; 61 62 } while (FALSE); 63 64 if (hFile) 65 { 66 ::CloseHandle(hFile); 67 } 68 69 return bRet; 70 } 71 72 73 BOOL CalculateHash(BYTE *pData, DWORD dwDataLength, ALG_ID algHashType, BYTE **ppHashData, DWORD *pdwHashDataLength) 74 { 75 HCRYPTPROV hCryptProv = NULL; 76 HCRYPTHASH hCryptHash = NULL; 77 BYTE *pHashData = NULL; 78 DWORD dwHashDataLength = 0; 79 DWORD dwTemp = 0; 80 BOOL bRet = FALSE; 81 82 83 do 84 { 85 // 获得指定CSP的密钥容器的句柄 86 bRet = ::CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT); 87 if (FALSE == bRet) 88 { 89 ShowError("CryptAcquireContext"); 90 break; 91 } 92 93 // 创建一个HASH对象, 指定HASH算法 94 bRet = ::CryptCreateHash(hCryptProv, algHashType, NULL, NULL, &hCryptHash); 95 if (FALSE == bRet) 96 { 97 ShowError("CryptCreateHash"); 98 break; 99 } 100 101 // 计算HASH数据 102 bRet = ::CryptHashData(hCryptHash, pData, dwDataLength, 0); 103 if (FALSE == bRet) 104 { 105 ShowError("CryptHashData"); 106 break; 107 } 108 109 // 获取HASH结果的大小 110 dwTemp = sizeof(dwHashDataLength); 111 bRet = ::CryptGetHashParam(hCryptHash, HP_HASHSIZE, (BYTE *)(&dwHashDataLength), &dwTemp, 0); 112 if (FALSE == bRet) 113 { 114 ShowError("CryptGetHashParam"); 115 break; 116 } 117 118 // 申请内存 119 pHashData = new BYTE[dwHashDataLength]; 120 if (NULL == pHashData) 121 { 122 bRet = FALSE; 123 ShowError("new"); 124 break; 125 } 126 ::RtlZeroMemory(pHashData, dwHashDataLength); 127 128 // 获取HASH结果数据 129 bRet = ::CryptGetHashParam(hCryptHash, HP_HASHVAL, pHashData, &dwHashDataLength, 0); 130 if (FALSE == bRet) 131 { 132 ShowError("CryptGetHashParam"); 133 break; 134 } 135 136 // 返回数据 137 *ppHashData = pHashData; 138 *pdwHashDataLength = dwHashDataLength; 139 140 } while (FALSE); 141 142 // 释放关闭 143 if (FALSE == bRet) 144 { 145 if (pHashData) 146 { 147 delete[]pHashData; 148 pHashData = NULL; 149 } 150 } 151 if (hCryptHash) 152 { 153 ::CryptDestroyHash(hCryptHash); 154 } 155 if (hCryptProv) 156 { 157 ::CryptReleaseContext(hCryptProv, 0); 158 } 159 160 return bRet; 161 } 162 163 164 int _tmain(int argc, _TCHAR* argv[]) 165 { 166 BYTE *pData = NULL; 167 DWORD dwDataLength = 0; 168 DWORD i = 0; 169 BYTE *pHashData = NULL; 170 DWORD dwHashDataLength = 0; 171 172 // 读取文件数据 173 GetFileData("C:\Users\Administrator\Desktop\paraseLED\white\process.exe", &pData, &dwDataLength); 174 175 // MD5 176 CalculateHash(pData, dwDataLength, CALG_MD5, &pHashData, &dwHashDataLength); 177 printf("MD5[%d] ", dwHashDataLength); 178 for (i = 0; i < dwHashDataLength; i++) 179 { 180 printf("%x", pHashData[i]); 181 } 182 printf(" "); 183 if (pHashData) 184 { 185 delete[]pHashData; 186 pHashData = NULL; 187 } 188 189 // SHA1 190 CalculateHash(pData, dwDataLength, CALG_SHA1, &pHashData, &dwHashDataLength); 191 printf("SHA1[%d] ", dwHashDataLength); 192 std::string hash_ = ""; 193 for (i = 0; i < dwHashDataLength; i++) 194 { 195 char temp[32] = { 0 }; 196 sprintf_s(temp, "%x", pHashData[i]); 197 hash_.append(temp); 198 printf("%x", pHashData[i]); 199 } 200 printf(" "); 201 std::cout << hash_.c_str() << std::endl; 202 printf(" "); 203 if (pHashData) 204 { 205 delete[]pHashData; 206 pHashData = NULL; 207 } 208 209 // SHA256 210 clock_t start, end; 211 start = clock(); 212 CalculateHash(pData, dwDataLength, CALG_SHA_256, &pHashData, &dwHashDataLength); 213 printf("SHA256[%d] ", dwHashDataLength); 214 for (i = 0; i < dwHashDataLength; i++) 215 { 216 printf("%x", pHashData[i]); 217 } 218 end = clock(); 219 printf(" "); 220 printf("timestamp = %f ", double(end - start) / CLOCKS_PER_SEC); 221 if (pHashData) 222 { 223 delete[]pHashData; 224 pHashData = NULL; 225 } 226 227 system("pause"); 228 return 0; 229 }
python code
1 # Python program to find SHA256 hexadecimal hash string of a file 2 import hashlib 3 import time 4 5 start = time.time() 6 filename = r'C:UsersAdministratorDesktopparaseLEDwhiteprocess.exe' 7 with open(filename,"rb") as f: 8 bytes = f.read() # read entire file as bytes 9 readable_hash = hashlib.sha256(bytes).hexdigest(); 10 print(readable_hash) 11 end = time.time() 12 print('timestamp = {}'.format(end - start))