我想用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计算的哈希。
问题在于,一方面,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;
}
QByteArray
的data()
返回一个指向存储在字节数组中的数据的指针。 指针可用于访问和修改组成数组的字节。 数据以'\0'终止,即对于'\0'终止符,返回字符串中的字节数为size()+1。 因此,我们不需要显式地添加\0
,QByteArray
正在为我们做这件事。 我们需要将+1
添加到大小,因为QByteArray
返回数组的大小,因为它不是\0
字符。
上面的代码为您的文件生成了CCBF4F0A52FD5AC59E18448EBADF2EF37C62F54F
,所以我猜它是一个正确的哈希。