Why I am getting the same MD5 hash for a QByteArray?



  • Hi again,

    I must be missing something fundamental here so I am hoping that someone could help point out my error. I am trying to resolve an MD5 hash on a QVarantMap which has three keys, two with QString() value and the third value is a QVariantMap().

    If I run the following code I get the same hash regardless of the data in my map.

    @
    QByteArray arr;
    foreach (QVariant v, vm) {
    arr.append(v.toChar());
    }

    QCryptographicHash md5Gen(QCryptographicHash::Md5);
    md5Gen.addData(arr);

    qDebug() << md5Gen.result().toHex();
    @

    What am I missing?

    Thanks


  • Moderators

    You are appending only a single character to your byte array. Maybe those are the same every time you run the code.

    I would change v.toChar() into v.toString(). Also, there is no need to keep the QCH object. Shorter code:
    @
    qDebug() << QCryptographicHash::hash(id,
    QCryptographicHash::Md5).toHex();
    @



  • Still, keep in mind toString() doesn't work for all types:
    [quote]QString QVariant::toString () const
    Returns the variant as a QString if the variant has type() String, Bool, ByteArray, Char, Date, DateTime, Double, Int, LongLong, StringList, Time, UInt, or ULongLong; otherwise returns an empty string.[/quote]

    Of course toChar() works for even fewer types !!!
    [quote]QChar QVariant::toChar () const
    Returns the variant as a QChar if the variant has type() Char, Int, or UInt; otherwise returns an invalid QChar.[/quote]

    --

    Also, you may wish to do something like this:
    @QByteArray arr;
    foreach (QVariant v, vm) {
    if(v.canConvert(QVariant::String)
    {
    arr.append("BEGIN_ELEMENT");
    arr.append((char) v.type());
    arr.append(v.toString().toUtf8());
    arr.append("END_ELEMENT");
    }
    else
    {
    qWarning("Skipped unsupported element!");
    }
    }@

    Otherwise, a String-type QVariant containing "42" (for example) and an Integer-type QVariant of value 42 would result in the very same Hash value! Also, the above code make sure that the string "foo" followed by the string "bar" doesn't get the same Hash value as the single string "foobar".

    BTW: It's also important to use toUtrf8() explicitly here! That's because the implicit QString to QByteArray conversion uses toAscii(), which usually is the same as toLatin1(). And this means that you'll get a nice "???????" string, if your QString contains any non-Latin characters! By calling toUtf8() you make your sure that any QString will get a unique Byte-code representation.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.