【问题标题】:Calculate SHA1 hash like Git with Qt C++使用 Qt C++ 像 Git 一样计算 SHA1 哈希
【发布时间】:2020-11-01 19:16:15
【问题描述】:

我想以与git hash-object 相同的方式散列文件,因此我可以将其与现有散列进行比较,但使用 Qt 和 C++。

this question 的答案显示了如何获得相同的哈希值,但没有一个示例使用 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 计算的哈希值。

【问题讨论】:

  • 您可以发布您尝试过的文件示例吗?链接问题中的空文件和 foobar 示例将是不错的选择。另外,QString::toUtf8 是否包含终止空字符?如果是这样,它会改变哈希结果,因为输入会不同。
  • 谢谢!使用QCryptographicHash 计算哈希是可行的。所以这不是如何做sha1哈希的问题。困难的部分是以 git 在散列时相同的方式组合所有部分......我添加了一个示例文件和所需的散列。

标签: c++ git qt hash sha1


【解决方案1】:

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

使用 QByteArray 比使用 const char * 方便得多。 在幕后,它始终确保数据后跟一个 \0 终结者,并使用隐式共享(copy-on-write)来减少 内存使用并避免不必要的数据复制。

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'结尾的,即返回字符串中的字节数是size() + 1对于'\0'结束符。因此,我们不需要显式添加\0QByteArray 正在为我们做这件事。我们需要将+1 添加到大小,因为QByteArray 返回数组的大小,因为它不会是\0 字符。

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

【讨论】:

  • 啊太棒了,这行得通!处理字节不是我的专长。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-07
  • 1970-01-01
  • 2010-12-08
  • 2015-04-13
  • 2022-10-02
  • 2016-10-17
相关资源
最近更新 更多