我从easyMule源代码中提取的HASH函数HASH出来的值和eMule中的不一样 不知道哪里没弄对 请高手帮我看一下 哪里还需要改一下 代码提取于CKnownFile
#include <io.h>
#include "MD4.h"
#include "otherfunctions.h"
void CreateHash(CFile* pFile, uint64 Length, uchar* pMd4HashOut)
{
ASSERT( pFile != NULL );
ASSERT( pMd4HashOut != NULL );
uint64 Required = Length;
uchar X[64*128];
CMD4 md4;
while (Required >= 64)
{
uint32 len;
if ((Required / 64) > sizeof(X)/(64 * sizeof(X[0])))
len = sizeof(X)/(64 * sizeof(X[0]));
else
len = (uint32)Required / 64;
pFile->Read(&X, len*64);
if (pMd4HashOut != NULL)
{
md4.Add(X, len*64);
}
Required -= len*64;
}
Required = Length % 64;
if (pMd4HashOut != NULL)
{
md4.Add(X, (uint32)Required);
md4.Finish();
md4cpy(pMd4HashOut, md4.GetHash());
}
}
bool CreateHash(FILE* fp, uint64 uSize, uchar* pucHash)
{
bool bResult = false;
CStdioFile file(fp);
try
{
CreateHash(&file, uSize, pucHash);
bResult = true;
}
catch (CFileException* ex)
{
ex->Delete();
}
return bResult;
}
bool CreateHash(const uchar* pucData, uint32 uSize, uchar* pucHash)
{
bool bResult = false;
CMemFile file(const_cast<uchar*>(pucData), uSize);
try
{
CreateHash(&file, uSize, pucHash);
bResult = true;
}
catch (CFileException* ex)
{
ex->Delete();
}
return bResult;
}
bool CreateFromFile(LPCTSTR in_directory, LPCTSTR in_filename, uchar fileHash[16])
{
// open file
CString strFilePath;
_tmakepathlimit(strFilePath.GetBuffer(MAX_PATH), NULL, in_directory, in_filename, NULL);
strFilePath.ReleaseBuffer();
FILE* file = _tfsopen(strFilePath, _T("rbS"), _SH_DENYNO); // can not use _SH_DENYWR because we may access a completing part file
if (!file){
tcout << _T("文件") << strFilePath << _T("打开失败! CodeDesc = ") << _tcserror(errno) << std::endl;
return false;
}
// set filesize
if (_filelengthi64(file->_file) > MAX_EMULE_FILE_SIZE)
{
fclose(file);
return false; // not supported by network
}
uint64 nFileSize = (uint64)_filelengthi64(file->_file);
// we are reading the file data later in 8K blocks, adjust the internal file stream buffer accordingly
setvbuf(file, NULL, _IOFBF, 1024*8*2);
CArray<uchar*, uchar*> hashlist;
// create hashset
uint64 togo = nFileSize;
UINT hashcount;
for (hashcount = 0; togo >= PARTSIZE; )
{
uchar* newhash = new uchar[16];
if (!CreateHash(file, PARTSIZE, newhash))
{
tcout << _T("Hash文件") << strFilePath << _T("失败! CodeDesc = ") << _tcserror(errno) << std::endl;
fclose(file);
delete[] newhash;
return false;
}
hashlist.Add(newhash);
togo -= PARTSIZE;
hashcount++;
}
uchar* lasthash = new uchar[16];
md4clr(lasthash);
if (!CreateHash(file, togo, lasthash))
{
tcout << _T("Hash文件") << strFilePath << _T("失败! CodeDesc = ") << _tcserror(errno) << std::endl;
fclose(file);
delete[] lasthash;
return false;
}
if (!hashcount)
{
md4cpy(fileHash, lasthash);
delete[] lasthash;
}
else
{
hashlist.Add(lasthash);
uchar* buffer = new uchar[hashlist.GetCount()*16];
for (int i = 0; i < hashlist.GetCount(); i++)
md4cpy(buffer+(i*16), hashlist[i]);
CreateHash(buffer, hashlist.GetCount()*16, fileHash);
delete[] buffer;
}
fclose(file);
file = NULL;
return true;
}
int main(void)
{
using namespace std;
string filePath;
while(getline(cin, filePath))
{
string::size_type pathEnd = filePath.find_last_of(_T('\\'));
string strDir = filePath.substr(0, pathEnd);
string strFile = filePath.substr(pathEnd + 1, string::npos);
uchar fileHash[16];
if(CreateFromFile(strDir.c_str(), strFile.c_str(), fileHash))
cout << "Hash = " << md4str(fileHash) << endl;
}
return 0;
}


































