首页 > 解决方案 > 短 QStrings 会与 qHash 发生冲突吗?

问题描述

我遇到了两个QString带有三个字符串的对象之间的冲突:

const QString one = "haç";
const QString two = "hek";
qDebug() << one << qHash(one);
qDebug() << two << qHash(two);

这是输出(我将其从控制台重定向到一个文件,以便正确输出特殊字符):

Debug: "haç" 103182
Debug: "hek" 103182

我习惯于将哈希冲突视为一种理论上的可能性,而不是在实践中会发生的事情。是否qHash更有可能对短字符串产生冲突?

(我在 Qt 5.15.1 中得到了这种行为。)

如果其他人想测试它,这是一个 MWE:

主文件

#include <QCoreApplication>
#include <QtDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    const QString one = "haç";
    const QString two = "hek";
    qDebug() << one << qHash(one);
    qDebug() << two << qHash(two);

    return a.exec();
}

无标题.pro

QT -= gui

CONFIG += c++11 console
CONFIG -= app_bundle

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
        main.cpp

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

标签: qthash

解决方案


查看 的源代码qHash,可以检查使用的算法:

uint h = seed;

if (seed && hasFastCrc32())
    return crc32(p, len, h);

for (size_t i = 0; i < len; ++i)
    h = 31 * h + p[i].unicode();

return h;

CRC32 仅在指定种子且 cpu 支持时使用。否则使用更简单的算法。

如果你指定一个种子(就像 QHash 和其他 Qt 类默认做的那样),你会得到不同的结果,即不会发生冲突。


推荐阅读