[Solved] Why my hash value is different when compare with the online hash generator?



  • My code snippet as follows:

    @
    foreach (const QModelIndex indexEx, selectedFiles)
    {
    QFile destinationFile,sourceFile;
    QDir destination(indexDest.data(QFileSystemModel::FilePathRole).toString());
    QString fileName(indexEx.data(QFileSystemModel::FileNameRole).toString());

        destinationFile.setFileName(destination.filePath(fileName));
        sourceFile.setFileName(indexEx.data(QFileSystemModel::FilePathRole).toString());
        sourceFile.copy(destinationFile.fileName());
    
        QCryptographicHash md5Generator(QCryptographicHash::Md5);
        QFile file(fileName);
        if (file.open(QFile::ReadOnly))
        {
            md5Generator.addData(file.readAll());
        }
        QString list = QString("The file name: " + fileName + "<br/>"
                               +"The Md5 value: " + md5Generator.result().toHex() + "<br/><br/>");
        ui->textBrowser_2->append(list);
    }
    

    @

    When I compare my checksum with online converter, the value is different. What's the reason behinds it?



  • This is my progress...
    I managed to get the md5 value and sha1 value for only .txt and .docx file only...
    For others, for example, .exe and .xlsx, I cannot get the correct md5 value and sha1 value...

    Below is my code snippet for my function:
    @
    void MainWindow::copy(QString string, QModelIndex indexVoidDest)
    {
    QDir dir(string);

    foreach(const QFileInfo item, dir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System))
    {
        if (item.isFile&#40;&#41;)
        {
            QFile destinationFile,sourceFile;
            QDir destination(indexVoidDest.data(QFileSystemModel::FilePathRole).toString());
            QString fileNameCopy(item.fileName());
    
            destinationFile.setFileName(destination.filePath(fileNameCopy));
            sourceFile.setFileName(item.absoluteFilePath());
            sourceFile.copy(destinationFile.fileName());
    
            QCryptographicHash md5Generator(QCryptographicHash::Md5);
            QCryptographicHash sha1Generator(QCryptographicHash::Sha1);
    
            QString fileHash(string);
            QFile file&#40;fileHash&#41;;
    
            if(file.open(QFile::ReadOnly))
                md5Generator.addData(file.readAll());
    
            file.close();
    
            if(file.open(QFile::ReadOnly))
                sha1Generator.addData(file.readAll());
    
            file.close();
    
            QString list = QString("File name: " + fileNameCopy + "<br/>"
                                   +"Location: " + string + "<br/>"
                                   +"Md5 value: " + md5Generator.result().toHex() + "<br/>"
                                   +"Sha1 value: " + sha1Generator.result().toHex() + "<br/><br/>");
            ui->textBrowser_2->append(list);
    
        }
    
        else if (item.isDir())
        {
            filemodel->mkdir(indexVoidDest,item.fileName());
            QString StringSe = (string + "/" + item.baseName());
            QModelIndex indexSeDest = filemodel->index(indexVoidDest.data(QFileSystemModel::FilePathRole).toString() + "/" + item.baseName());
            copy(StringSe,indexSeDest);
        }
    }
    

    }
    @


  • Moderators

    I've deleted your duplicated thread.

    There are some things that can change the checksum here: file.readAll() returns a QByteArray, which will be automatically terminated with \0 - even if the file is not. To avoid this, try reading the file with QDataStream, or use constData() method from QByteArray.

    Also, you are needlessly wasting memory and CPU time by reading the file twice. Read it once, store the result in a QByteArray, and use that to calculate both hashes.



  • Thanks for deleting my duplicated thread.

    I know that when i read the file twice, it will require a lot of memory,
    but when I combine in a single 'if', the Sha1 value turns to be wrong.

    @
    if(file.open(QFile::ReadOnly))
    {
    md5Generator.addData(file.readAll());
    sha1Generator.addData(file.readAll());
    }
    file.close();
    @

    Can you explain why the Sha1 value turns to be something else??? Not the true Sha1 value for the file...

    p/s: I will try to write the code using QDataStream... Thanks for the suggestion...



  • sierdzio, I think I get what you mean... :)


  • Moderators

    I've meant something like this:
    @
    if(file.open(QFile::ReadOnly))
    {
    QByteArray data(file.readAll());
    md5Generator.addData(data); // or, please try with data.constData()
    sha1Generator.addData(data); // or, please try with data.constData()
    }
    @

    All checksum algorithms are very sensitive to data changes. Adding or changing a single bit (just a one or zero) will change the result completely. This is how those functions are designed and actually it's their major advantage.

    So, when a function in your code adds something to the data, or does not read all the data (maybe the online checker you are using includes file header or file name in the checksummed data?), the result will be different. But here is the thing: the checksum is still valid - just based on a different data. If you use the same method in all places in your code, it will work just fine.

    In summary: if you want to have the same result as your online checking tool, you need to pass the same data to your filter - then it will work.



  • sierdzio,
    I know checksum algorithms are very sensitive, that's why sometime, I don't know what's wrong with my coding...
    Thanks for the clarification...



  • Why the .size() does return the size of the file???
    Can anyone show me the correct way on how to use .size()???

    My code snippet as follow:

    @
    foreach (const QModelIndex indexEx, selectedFiles)
    {
    QFile destinationFile,sourceFile;
    QDir destination(indexDest.data(QFileSystemModel::FilePathRole).toString());
    QString fileNameCopy(indexEx.data(QFileSystemModel::FileNameRole).toString());

        destinationFile.setFileName(destination.filePath(fileNameCopy));
        sourceFile.setFileName(indexEx.data(QFileSystemModel::FilePathRole).toString());
        sourceFile.copy(destinationFile.fileName());
    
        QCryptographicHash md5Generator(QCryptographicHash::Md5);
        QCryptographicHash sha1Generator(QCryptographicHash::Sha1);
    
        QString fileHash(indexEx.data(QFileSystemModel::FilePathRole).toString());
        QFile file&#40;fileHash&#41;;
        QFileInfo fileInfo(file&#41;;
    
        if(file.open(QFile::ReadOnly))
        {
            QByteArray data(file.readAll());
            md5Generator.addData(data);
            sha1Generator.addData(data);
            file.close();
        }
    
        qlonglong size = fileInfo.size()/1024;
        QString list = QString("File name: " + fileNameCopy + "<br/>"
                               +"Location: " + indexEx.data(QFileSystemModel::FilePathRole).toString() + "<br/>"
                               +"Size: " + size + " K <br/>"
                               +"Date created: " + fileInfo.created().toString() + "<br/>"
                               +"Date modified: " + fileInfo.lastModified().toString() + "<br/>"
                               +"Date accessed: " + fileInfo.lastRead().toString() + "<br/>"
                               +"Md5 value: " + md5Generator.result().toHex() + "<br/>"
                               +"Sha1 value: " + sha1Generator.result().toHex() + "<br/><br/>");
        ui->textBrowser_2->append(list);
    }
    

    @

    In my case, it does display an output but just a raw data or something like that...



  • I already solve problem regarding the size of the files... :)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.