使用 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;
}
QByteArray
的data()
是返回指向字节数组中存储的数据的指针。指针可用于访问和修改组成数组的字节。数据以'\0'结尾,即返回字符串的字节数为size() + 1为'\0'结尾。 因此不需要显式添加[=12 =]
, QByteArray
正在为我们做这件事。我们需要将 +1
添加到大小,因为 QByteArray
returns 数组的大小,因为它没有 [=12=]
个字符。
上面的代码为您的文件生成了 ccbf4f0a52fd5ac59e18448ebadf2ef37c62f54f
,所以我猜它是一个正确的散列。
我想用与 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;
}
QByteArray
的data()
是返回指向字节数组中存储的数据的指针。指针可用于访问和修改组成数组的字节。数据以'\0'结尾,即返回字符串的字节数为size() + 1为'\0'结尾。 因此不需要显式添加[=12 =]
, QByteArray
正在为我们做这件事。我们需要将 +1
添加到大小,因为 QByteArray
returns 数组的大小,因为它没有 [=12=]
个字符。
上面的代码为您的文件生成了 ccbf4f0a52fd5ac59e18448ebadf2ef37c62f54f
,所以我猜它是一个正确的散列。