使用 Qt C++ 计算类似 Git 的 SHA1 哈希

Calculate SHA1 hash like Git with Qt C++

我想用与 git hash-object 相同的方式对文件进行哈希处理,这样我就可以将它与现有的哈希进行比较,但使用的是 Qt 和 C++。

this question 的答案显示了如何获得相同的散列,但 none 的示例使用 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( "[=11=]" ).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 计算的哈希值。

问题在于,一方面,QString 忽略了 [=12=] 作为终止字符串,另一方面,QByteArray 总是附加额外的 [=12=]。来自 Qt 的文档:

Using QByteArray is much more convenient than using const char *. Behind the scenes, it always ensures that the data is followed by a [=12=] terminator, and uses implicit sharing (copy-on-write) to reduce memory usage and avoid needless copying of data.

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

因此,在您的案例中,每个 addData 都会向要散列的数据添加额外的 [=12=]。一些解决方法可能是以下代码:

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'结尾,即返回字符串的字节数为size() + 1为'\0'结尾。 因此不需要显式添加[=12 =], QByteArray 正在为我们做这件事。我们需要将 +1 添加到大小,因为 QByteArray returns 数组的大小,因为它没有 [=12=] 个字符。

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