1

I have code, which generate md5 for strings. Now I want to add generation md5 for files. It work's with txt files(xml, html, txt etc), but when I try to do it with binary file(zip, bin, apk, etc) I see wrong result. How can I correctly read bin file in (char*) in order to generate valid hash?

I tried to use TextStream, but result is not valid

QFile file(fileName);
file.open(QIODevice::ReadOnly);

QTextStream in(&file);
QString t = in.readAll();
file.close();

string res = md5(t.toStdString());

Also I tried to use QByteArray and after that convert byteArray to char* But it doesn't work correctly too. How can I fix it?

Pein
  • 1,059
  • 3
  • 10
  • 31
  • *Never ever use `QString` and `QTextStream` for binary data*. They are for Unicode text, decoded from bytes in a well-known encoding. Trying to use them for binary data will happily and silently screw it up. – Matteo Italia Oct 18 '15 at 12:27
  • Ok, but what can I use in order to do it? – Pein Oct 18 '15 at 12:29
  • You may want to consider QCrytographicHash. Qt has builtin md5 generation. http://doc.qt.io/qt-5/qcryptographichash.html – drescherjm Oct 18 '15 at 12:38

1 Answers1

5

Never ever use QString and QTextStream for binary data. They are for Unicode text, decoded from bytes in a well-known encoding. Trying to use them for binary data will happily and silently screw it up, as QString by default will try to interpret the input data using some encoding to translate it to its UTF-16 storage, silently skipping whatever it cannot understand.

The class for storing binary data is QByteArray, and you can read a whole file in it using the QFile::read() method.

QByteArray data;
{
    QFile file(fileName);
    file.open(QIODevice::ReadOnly);
    data.readAll();
}

string res = md5(std::string(data.begin(), data.end());

Notice that I built the std::string with the range-based constructor, since just using std::string(data.data()) (constructor from a C string) would stop at the first embedded NUL.

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
  • I tried to use QByteArray, but I got wrong result too :( So, I think it is a problem with my md5 implementation. But for strings and txt files it works – Pein Oct 18 '15 at 12:35
  • Let's see your code... you can get it wrong with `QByteArray` too if you don't do as I did (e.g. you don't build the `std::string` with the range-based constructor). – Matteo Italia Oct 18 '15 at 12:38
  • Oh, sorry, your Code works, thank you) – Pein Oct 18 '15 at 12:53