提问者:小点点

用Qt C++计算SHA1散列,与Git类似


我想用Git hash-object同样的方式散列文件,这样我就可以将它与现有的散列进行比较,但使用的是Qt和C++。

这个问题的答案显示了如何获得相同的散列,但是没有一个示例使用C++。

到目前为止,这是我们所尝试的:

QString fileName = entry.toObject().value( "name" ).toString();
QByteArray shaJson = entry.toObject().value( "sha" ).toString().toUtf8();
QByteArray shaFile;

QFile f( QString( "%1/%2" ).arg( QCoreApplication::applicationDirPath() ).arg( fileName ) );
if( f.open(QFile::ReadOnly ) )
{
QCryptographicHash hash(QCryptographicHash::Sha1);
hash.addData( QString( "blob " ).toUtf8() ); // start with the string "blob "
hash.addData( QString( "%1" ).arg( f.size() ).toUtf8() ); // add size in bytes of the content
hash.addData( QString( "\0" ).toUtf8() ); // null byte
hash.addData( f.readAll() ); // actual file content
shaFile = hash.result().toHex();
if( shaFile != shaJson ){

}
}

如何用Qt实现这种散列方法?

编辑:

下面是一个示例哈希输出:CCBF4F0A52FD5AC59E18448EBADF2EF37C62F54F使用GIT hash-object从以下文件计算:https://raw.githubusercontent.com/ilia3101/mlv-app/master/pixel_maps/80000301_1808x1007.fpm,因此这也是我们喜欢用Qt计算的哈希。


共1个答案

匿名用户

问题在于,一方面,QString忽略\0作为终止字符串,另一方面,QByteArray总是追加额外的\0。 来自Qt的文档:

使用QByteArray比使用常量char*方便得多。 在幕后,它总是确保数据后面跟着一个\0终止符,并使用隐式共享(写时复制)来减少内存使用,避免不必要的数据复制。

https://doc.qt.io/qt-5/QByteArray.html

因此,在您的示例中,每个adddata都是在要散列的数据中添加额外的\0。 一些解决办法可能是以下代码:

QFile file(path);
if( file.open(QFile::ReadOnly ) )
{
    QCryptographicHash hash(QCryptographicHash::Sha1);
    QByteArray header = QString("blob %1").arg(file.size()).toUtf8();
    hash.addData(header.data(), header.size() + 1);
    hash.addData(file.readAll());

    shaFile = hash.result().toHex();
    qDebug() << shaFile;
}

QByteArraydata()返回一个指向存储在字节数组中的数据的指针。 指针可用于访问和修改组成数组的字节。 数据以'\0'终止,即对于'\0'终止符,返回字符串中的字节数为size()+1。 因此,我们不需要显式地添加\0QByteArray正在为我们做这件事。 我们需要将+1添加到大小,因为QByteArray返回数组的大小,因为它不是\0字符。

上面的代码为您的文件生成了CCBF4F0A52FD5AC59E18448EBADF2EF37C62F54F,所以我猜它是一个正确的哈希。

相关问题


MySQL Query : SELECT * FROM v9_ask_question WHERE 1=1 AND question regexp '(qt|c++|计算|sha1|散|列|git|类似)' ORDER BY qid DESC LIMIT 20
MySQL Error : Got error 'repetition-operator operand invalid' from regexp
MySQL Errno : 1139
Message : Got error 'repetition-operator operand invalid' from regexp
Need Help?