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

Calculate SHA1 hash like Git with Qt C++

本文关键字:Git SHA1 哈希 Qt C++ 计算 使用      更新时间:2023-10-16

我想以与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( "" ).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忽略了作为终止字符串,另一方面,QByteArray总是附加额外的。来自Qt的文档:

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

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

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

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因此,我们不需要显式添加QByteArray是为我们做这件事的。我们需要将+1添加到大小中,因为QByteArray返回数组的大小,因为它不会是字符。

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