Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [Solved] QCryptographicHash::hash() on QIODevice.read() and QCryptographicHash.addData(QIODevice).result() give different values

[Solved] QCryptographicHash::hash() on QIODevice.read() and QCryptographicHash.addData(QIODevice).result() give different values

Scheduled Pinned Locked Moved General and Desktop
qcryptographichqiodevice
4 Posts 2 Posters 2.2k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • G Offline
    G Offline
    Gallaecio
    wrote on 27 Jul 2015, 18:54 last edited by Gallaecio
    #1

    I want to generate an MD4 from a file. Reading a test file using the following two different approaches gives different results.

    The result of the second approach is correct (as the third-party software that I want to emulate, aMule, shows).
    The result of the first approach is incorrect.
    I want to follow the first approach because, for files greater than the specified CHUNK_SIZE, I want to go on a loop and get MD4 hashes of each chunk.

    // Unexpected output.
    const qint64 CHUNK_SIZE = 9728000;
    char* data = new char[CHUNK_SIZE];
    ioDevice.seek(0);
    ioDevice.read(data, CHUNK_SIZE); // Returns the expected size.
    QByteArray hash = QCryptographicHash::hash(data, QCryptographicHash::Md4);
    std::cout << "ioDevice.read() hash: " << hash.toHex().toStdString() << std::endl;
    
    // Expected output, aMule’s.
    ioDevice.seek(0);
    QCryptographicHash fileHash(QCryptographicHash::Md4);
    if (fileHash.addData(&ioDevice))
        std::cout << "fileHash.addData() hash: " << fileHash.result().toHex().toStdString() << std::endl;
    

    I’m obviously doing something wrong in the first approach. What is it?

    Note: The code here assumes that the file fits CHUNK_SIZE, as this is just a test code to be used on a file that is much smaller than the specified CHUNK_SIZE.

    G 1 Reply Last reply 28 Jul 2015, 05:41
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 27 Jul 2015, 20:28 last edited by
      #2

      Hi,

      Your array contains uninitialized data and your read call won't necessarily fill it thus you will likely get different result for every call to that function. You are using more data that you read from the device.

      Your second code sample will only read the content of the ioDevice nothing more.

      Hope it helps

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      G 1 Reply Last reply 27 Jul 2015, 20:52
      0
      • S SGaist
        27 Jul 2015, 20:28

        Hi,

        Your array contains uninitialized data and your read call won't necessarily fill it thus you will likely get different result for every call to that function. You are using more data that you read from the device.

        Your second code sample will only read the content of the ioDevice nothing more.

        Hope it helps

        G Offline
        G Offline
        Gallaecio
        wrote on 27 Jul 2015, 20:52 last edited by
        #3

        @SGaist Many thanks for your help.

        The reported MD4 of both approaches stays the same on each call. Also, if I use strncpy() to copy the read data onto a new array that is only as big as the read data, I still get the same results:

        const qint64 CHUNK_SIZE = 9728000;
        char* data = new char[CHUNK_SIZE];
        ioDevice.seek(0);
        qint64 read_size = ioDevice.read(data, CHUNK_SIZE);
        char* actual_data = new char[read_size];
        strncpy(actual_data, data, read_size);
        QByteArray hash = QCryptographicHash::hash(actual_data, QCryptographicHash::Md4);
        std::cout << "ioDevice.read() hash: " << hash.toHex().toStdString() << std::endl;
        
        1 Reply Last reply
        0
        • G Gallaecio
          27 Jul 2015, 18:54

          I want to generate an MD4 from a file. Reading a test file using the following two different approaches gives different results.

          The result of the second approach is correct (as the third-party software that I want to emulate, aMule, shows).
          The result of the first approach is incorrect.
          I want to follow the first approach because, for files greater than the specified CHUNK_SIZE, I want to go on a loop and get MD4 hashes of each chunk.

          // Unexpected output.
          const qint64 CHUNK_SIZE = 9728000;
          char* data = new char[CHUNK_SIZE];
          ioDevice.seek(0);
          ioDevice.read(data, CHUNK_SIZE); // Returns the expected size.
          QByteArray hash = QCryptographicHash::hash(data, QCryptographicHash::Md4);
          std::cout << "ioDevice.read() hash: " << hash.toHex().toStdString() << std::endl;
          
          // Expected output, aMule’s.
          ioDevice.seek(0);
          QCryptographicHash fileHash(QCryptographicHash::Md4);
          if (fileHash.addData(&ioDevice))
              std::cout << "fileHash.addData() hash: " << fileHash.result().toHex().toStdString() << std::endl;
          

          I’m obviously doing something wrong in the first approach. What is it?

          Note: The code here assumes that the file fits CHUNK_SIZE, as this is just a test code to be used on a file that is much smaller than the specified CHUNK_SIZE.

          G Offline
          G Offline
          Gallaecio
          wrote on 28 Jul 2015, 05:41 last edited by
          #4

          I’ve found out what my issue was. I was reading binary files, and char arrays end at null characters ('\0'), which binary files may have.

          I found out that I can use a QByteArray all the way instead of an array of chars, resulting in a more readable that works regardless of the null characters in the binary file:

          const qint64 CHUNK_SIZE = 9728000;
          ioDevice.seek(0);
          QByteArray data = ioDevice.read(CHUNK_SIZE);
          QByteArray hash = QCryptographicHash::hash(data, QCryptographicHash::Md4);
          std::cout << "ioDevice.read() hash: " << hash.toHex().toStdString() << std::endl;
          
          1 Reply Last reply
          0

          1/4

          27 Jul 2015, 18:54

          • Login

          • Login or register to search.
          1 out of 4
          • First post
            1/4
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved