Using MD5 engine in POCO libraries to hash binary array - poco-libraries

New to Poco libraries.
I want to calculate a MD5 value on a binary array. I first wrote in hex decimal format, then convert to a binary string. Then I call MD5 engine. Why my code does not work?
std::istringstream message1 ("0162010d00000000000000000000000000000000000103030303030303030303030301a0c000033131394040767a7733672e636f6d2c06313030300506000056cc2806000000011a0c00003297c806000000001f11300003297cf12303030303030303030303030303030301a0c00003297cb06000000011a0e000028af08083331313237301a0a000028af17040a001a15000028af160f821301845802130184015ae401");
Poco::HexBinaryDecoder message2 (message1);
std::string message3;
message2 >> message3;
MD5Engine engine;
engine.update (message3.data(), message1.str().length() / 2);
cout << "\n digest1: " << DigestEngine::digestToHex(engine.digest());
Thanks for help!.
DD

Related

Pass a string from ECL to C++

I'm trying to get into the fascinating world of Common Lisp embedded in C++. My problem is that I can't manage to read and print from c++ a string returned by a lisp function defined in ECL.
In C++ I have this function to run arbitrary Lisp expressions:
cl_object lisp(const std::string & call) {
return cl_safe_eval(c_string_to_object(call.c_str()), Cnil, Cnil);
}
I can do it with a number in this way:
ECL:
(defun return-a-number () 5.2)
read and print in C++:
auto x = ecl_to_float(lisp("(return-a-number)"));
std::cout << "The number is " << x << std::endl;
Everything is set and works fine, but I don't know to do it with a string instead of a number. This is what I have tried:
ECL:
(defun return-a-string () "Hello")
C++:
cl_object y = lisp("(return-a-string)");
std::cout << "A string: " << y << std::endl;
And the result of printing the string is this:
A string: 0x3188b00
that I guess is the address of the string.
Here it is a capture of the debugger and the contents of the y cl_object. y->string.self type is an ecl_character.
Debug
(Starting from #coredump's answer that the string.self field provides the result.)
The string.self field is defined as type ecl_character* (ecl/object.h), which appears to be given in ecl/config.h as type int (although I suspect this is slightly platform dependent). Therefore, you will not be able to just print it as if it was a character array.
The way I found worked for me was to reinterpret it as a wchar_t (i.e. a unicode character). Unfortunately, I'm reasonably sure this isn't portable and depends both on how ecl is configured and the C++ compiler.
// basic check that this should work
static_assert(sizeof(ecl_character)==sizeof(wchar_t),"sizes must be the same");
std::wcout << "A string: " << reinterpret_cast<wchar_t*>(y->string.self) << std::endl;
// prints hello, as required
// note the use of wcout
The alternative is to use the lisp type base-string which does use char (base-char in lisp) as its character type. The lisp code then reads
(defun return-a-base-string ()
(coerce "Hello" 'base-string))
(there may be more elegant ways to do the conversion to base-string but I don't know them).
To print in C++
cl_object y2 = lisp("(return-a-base-string)");
std::cout << "Another: " << y2->base_string.self << std::endl;
(note that you can't mix wcout and cout in the same program)
According to section 2.6 Strings of The ECL Manual, I think that the actual character array is found by accessing the string.self field of the returned object. Can you try the following?
std::cout << y->string.self << std::endl;
std::string str {""};
cl_object y2 = lisp("(return-a-base-string)");
//get dimension
int j = y2->string.dim;
//get pointer
ecl_character* selv = y2->string.self;
//do simple pointer addition
for(int i=0;i<j;i++){
str += (*(selv+i));
}
//do whatever you want to str
this code works when the string is build from ecl_characters
from the documentation:
"ECL defines two C types to hold its characters: ecl_base_char and ecl_character.
When ECL is built without Unicode, they both coincide and typically match unsigned char, to cover the 256 codes that are needed.
When ECL is built with Unicode, the two types are no longer equivalent, with ecl_character being larger.
For your code to be portable and future proof, use both types to really express what you intend to do."
On my system the return-a-base-string is not needed, but I think it could be good to add for compatibility. I use the (ecl) embedded CLISP 16.1.2 version.
The following piece of code reads a string from lisp and converts to C++ strings types - std::string and c-string- and store them on C++ variables:
// strings initializations: string and c-string
std::string str2 {""};
char str_c[99] = " ";
// text read from clisp, whatever clisp function that returns string type
cl_object cl_text = lisp("(coerce (text-from-lisp X) 'base-string)");
//cl_object cl_text = lisp("(text-from-lisp X)"); // no base string conversions
// catch dimension
int cl_text_dim = cl_text->string.dim;
// complete c-string char by char
for(int ind=0;i<cl_text_dim;i++){
str_c[i] = ecl_char(cl_text,i); // ecl function to get char from cl_object
}
str_c[cl_text_dim] ='\0'; // end of the c-string
str2 = str_c; // get the string on the other string type
std::cout << "Dim: " << cl_ text_dim << " C-String var: " << str_c() << " String var << str2 << std::endl;
It is a slow process as passing char by char but it is the only way by the moment I know. Hope it helps. Greetings!

Get a string representation of a single byte from QByteArray?

I have a QByteArray i create manually:
QByteArray hexArray(QByteArray::fromHex("495676"));
If this was encoded ASCII it would be "IVv".
If I want to get a single byte of data from that array.
I can do that like this:
qDebug() << messageToBeSent_raw[0];
However, that outputs I, which is correct but I would like to get 49. What I'm looking for is an equivalent of the QByteArray::toHex() just for a single byte. Is there a way to do it?
You can use QString::number.
qDebug() << QString::number(hexArray[0], 16);

Qt parse string of undefined size from a binary data stream

I have a binary data stream which contains data that should be interpreted as a Qstring. Starting from the third byte. Here is how the package is generated (on a client).
QByteArray package;
package.append( QByteArray::fromHex("0002") ); // First two bytes
package.append( "filename.txt" ); // String of undefined size
package.append( QByteArray::fromHex("00")); // End of string
The decoding is done on a different machine (server). I would like to get a Qstring of value "filename.txt" from the QByteArray package without relying on the size of the string (since the server doesn't have that information) but on the string terminator 00. How can this be achieved?
Since this decoding will be done on a different machine, how should the raw data be generated on the client to avoid problems with endianess?
You should wrap the QByteArray in a QDataStream so you can specify the endianess explicitly and make use of the stream operators
QByteArray package;
QDataStream stream(package, QIODevice::WriteOnly);
stream.setByteOrder( QDataStream::BigEndian);
stream << static_cast<quint16>(0x0002); // First two bytes
stream << "filename.txt"; // String of undefined size
// no need to write terminating 0 because data stream will prepend length
then you can read in the other direction:
QByteArray package;
QDataStream stream(package, QIODevice::WriteOnly);
stream.setByteOrder( QDataStream::BigEndian);
quint16 id;
stream >> id; // First two bytes
char* filename;
stream >> filename; // String of undefined size
QString file = QString.fromLatin1(filename);
delete[] filename; //cleanup
or you can pass a QString to the stream in the first place and not need to deal with the char array:
QByteArray package;
QDataStream stream(package, QIODevice::WriteOnly);
stream.setByteOrder( QDataStream::BigEndian);
stream << static_cast<quint16>(0x0002); // First two bytes
stream << QStringLiteral("filename.txt"); // String of undefined size
note that this will write in utf16 meaning it is unicode enabled
the serialization format is documented at http://qt-project.org/doc/qt-5.0/qtcore/datastreamformat.html

Not able to Seralize QHash to DataStream

while leaning about QHash and serializing QHash to DataStream I got an error with the following code.
typedef QHash <quint32,QString> hashtype1;
typedef QHash <QLocale::Language,hashtype1> hashtype;
hashtype1 hash;
hash.insert(1, "Key1");
hash.insert(2, "Key2");
hashtype hash1;
hash1.insert(QLocale::English, hash);
hash1.insert(QLocale::French, hash);
QByteArray ba;
QByteArray ba1;
QDataStream ds(&ba, QIODevice::ReadWrite);
QDataStream ds1(&ba1, QIODevice::ReadWrite);
ds << hash;
ds1 << hash1;
qDebug() << ds.device()->readAll();
ds.device()->reset();
ds1.device()->reset();
hashtype1 hashcopy;
ds >> hashcopy;
hashtype hash1copy;
ds1 >> hash1copy;
The last statement is giving an error saying
/usr/include/qt4/QtCore/qdatastream.h:362: error: no match for ‘operator>>’ in ‘in >> k’
I am not able to correct this..
Am I doing somthing wrong??
How can I correct this?
The problem is that there are no QDataStream operators for QLocale::Language. When streaming out this works because it gets automatically converted to an integer type. It can't do this for streaming in. So you will either need to change your QHash to use a different template parameter for the key or write streaming operators for QLocale::Language (which should be trivial, you just need to cast it to/from int).

How to get magic number of a binary file

There is a magic number associated with each binary file , does anyone know how to retrieve this information from the file?
file <file_name>
magic numbers are usually stored in (linux):
/usr/share/file/magic
also check this link, someone was trying to use libmagic to get the information in C program, might be useful if you're writing something yourself.
Use libmagic from the file package to try and sniff out the type of file if that's your goal.
There are no general "magic" numbers in binary files on unix, though different formats might define their own. The above library knows about many of those and also use various other heuristics to try and figure out the format/type of file.
The unix file command uses magic number. see the file man page for more.(and where to find the magic file )
Read this: http://linux.die.net/man/5/magic
It's complex, and depends on the specific file type you're looking for.
There is a file command which in turn uses a magic library, the magic library reads from a file found in /etc called magic (this is installation dependant and may vary), which details what are the first few bytes of the file and tells the file what kind of a file it is, be it, jpg, binary, text, shell script. There is an old version of libmagic found on sourceforge. Incidentally, there is a related answer to this here.
Hope this helps,
Best regards,
Tom.
Expounding on #nos's answer:
Example below uses the default magic database to query the file passed on the command line. (Essentially an implementation of the file command. See man libmagic for more details/functions.
#include <iostream>
#include <magic.h>
#include <cassert>
int main(int argc, char **argv) {
if (argc == 1) {
std::cerr << "Usage " << argv[0] << " [filename]" << std::endl;
return -1;
}
const char * fname = argv[1];
magic_t cookie = magic_open(0);
assert (cookie !=nullptr);
int rc = magic_load(cookie, nullptr);
assert(rc == 0);
auto f= magic_file(cookie, fname);
if (f ==nullptr) {
std::cerr << magic_error(cookie) << std::endl;
} else {
std::cout << fname << ' ' << f << std::endl;
}
}

Resources