我想做一个7z文件的哈希。我可以用二进制文件打开文件,如果在.7z文件中,可以获取存档.7z的哈希值。
如果我在存档.7z中有2个小的.txt文件,那么哈希就不好了。如果我想对1.8GB这样的大.txt文件的一个存档.7z进行哈希处理,那么我的哈希就不一样了。
对于一个大文件,我在这里只做一个循环,这是不好的:
while(!file.eof())
{
char buff[bufferSize];
memset(buff,0x00,sizeof(buff));
file.read(buff,bufferSize);
size_t nbRead = file.gcount();
SHA512_Update( &ctx, &buff[0], nbRead );
}
你能帮我看看如何阅读这个.7z文件吗?
感谢您的帮助
这是源代码。
#include <atlstr.h>
#include <LibOpenSSL.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <iostream>
using namespace std;
我的职能:
bool HashFile::generateHashInFile()
{
bool bHashDone = false;
std::ofstream fileHash;
std::ifstream file;
// I do this to try to hash 6 files
for(int i=0;i<6;i++)
{
if(i==0){
m_NameFileHash="D:\\TODELETE\\0.sha512";
m_NameFile="D:\\TODELETE\\0.7z";
}
if(i==1){
m_NameFileHash="D:\\TODELETE\\1.sha512";
m_NameFile="D:\\TODELETE\\1.7z";
}
if(i==2){
m_NameFileHash="D:\\TODELETE\\2.sha512";
m_NameFile="D:\\TODELETE\\2.7z";
}
if(i==3){
m_NameFileHash="D:\\TODELETE\\3.sha512";
m_NameFile="D:\\TODELETE\\3.7z";
}
if(i==4){
m_NameFileHash="D:\\TODELETE\\4.sha512";
m_NameFile="D:\\TODELETE\\4.7z";
}
if(i==5){
m_NameFileHash="D:\\TODELETE\\5.sha512";
m_NameFile="D:\\TODELETE\\5.7z";
}
fileHash.clear();
file.clear();
SystemConfiguration::COutilsCommun::OpenOStream(fileHash,m_NameFileHash.c_str());
SystemConfiguration::COutilsCommun::OpenIStream(file, m_NameFile.c_str());
//this is useful to open a stream SystemConfiguration::COutilsCommun::OpenOStream(fileHash,m_NameFileHash.c_str());
// if std::ifstream file is huge ( I have one error )
if(!file)
{
std::cout << "impossible d'ourvrir le fichier : " << m_NameFile.c_str() <<std::endl;
std::cout << "taille du fichier : " << file.tellg() <<std::endl;
}
if(!fileHash)
{
std::cout << "impossible de creer le fichier : " << m_NameFileHash.c_str() <<std::endl;
}
if( (file)&& (fileHash) )
{
unsigned char digest[SHA512_DIGEST_LENGTH];
std::string mdString(SHA512_DIGEST_LENGTH*2,' ');
std::stringstream buffer; //// variable with the content of the file
// buffer << file.rdbuf();
const size_t bufferSize = 1024;
//vector<char> bufferX(bufferSize);
//char buff[bufferSize];
char * finalBuff = NULL;
SHA512_CTX ctx;
SHA512_Init( &ctx );
if(!file.is_open())
{
cout << "Unable to open file" << endl;
bHashDone = false;
}
file.seekg(0,std::ios::beg);
while(!file.eof())
{
char buff[bufferSize];
memset(buff,0x00,sizeof(buff));
file.read(buff,bufferSize);
size_t nbRead = file.gcount();
SHA512_Update( &ctx, &buff[0], nbRead );
}
SHA512_Final(digest, &ctx);
bHashDone = true;
vector<char> szBuffer(SHA512_DIGEST_LENGTH*2 + 1);
for ( int i = 0 ; i < SHA512_DIGEST_LENGTH ; ++i ) {
const char tabCaractHexa[] = "0123456789abcdef";
int valueToConvert = digest[i];
int first = (valueToConvert >> 4) & 0xF; // part 'hight' of the byte
int second = valueToConvert & 0xF; // lower part -> base unit 16
szBuffer[i*2] = tabCaractHexa[first]; // conversion 0 to 15 in '0' to 'F'
szBuffer[i*2+1] = tabCaractHexa[second]; // conversion 0 to 15 in '0' to 'F'
}
szBuffer[SHA512_DIGEST_LENGTH*2] = '\0';
std::string mdString2(&szBuffer[0]);
cout << "SHA512 digest of " << m_NameFile << " is " << mdString2 << endl;
fileHash << mdString2;
//clean the content of the variables
buffer.clear();
mdString.clear();
mdString2.clear();
m_NameFile.clear();
m_NameFileHash.clear();
} //end if( (file)&& (fileHash) )
if( file.is_open() )
{
SystemConfiguration::COutilsCommun::CloseIStream(file,m_NameFile.c_str());
}
if( fileHash.is_open() )
{
SystemConfiguration::COutilsCommun::CloseOStream(fileHash,m_NameFileHash.c_str());
}
fileHash.close();
file.close();
}//le for pour test
return bHashDone;
}
catch ( std::exception e)
{
std::cout << "impossible d'ourvrir le fichier : " << m_NameFile.c_str() <<std::endl;
if( file.is_open() )
{
SystemConfiguration::COutilsCommun::CloseIStream(file,m_NameFile.c_str());
}
if( fileHash.is_open() )
{
SystemConfiguration::COutilsCommun::CloseOStream(fileHash,m_NameFileHash.c_str());
}
}
return bHashDone;
}
else
{
std::cout << "\n\n Merci de specifier un nom de fichier à hasher et un nom de fichier qui contient le hash \n\n" <<std::endl;
return bHashDone;
}
}