Mar 15, 2020 at 6:18pm UTC
I want to generate hash of struct prop so for i need to copy the structure into a byte array and pass it to md5 function of openssl. I want to know how to copy struct prop which has another structure of string and some integer value into a char array. Please let me know if anyone has done this?
struct innerprop
{
string a;
string b;
string c;
}
struct prop
{
string id;
string name;
int p;
innerprop ip;
}
Mar 15, 2020 at 7:25pm UTC
One terse way is to do something like this:
1 2 3 4 5 6 7 8
using u8 = std::uint8_t;
using u8_string = std::basic_string<u8>;
u8_string to_u8_string(std::string const & f)
{ return u8_string(reinterpret_cast <u8 const *>(f.c_str()), f.size()); }
u8_string serialize(prop const & p)
{ return to_u8_string(fp.id) + to_u8_string(p.name) /* ... */ ; }
But it does imply some overhead - which may or may not be swallowed by the time required to compute the digest.
Full example:
http://coliru.stacked-crooked.com/a/1ead2e262fc1d71e
Last edited on Mar 15, 2020 at 7:27pm UTC
Mar 15, 2020 at 9:55pm UTC
dutch wrote:You could maybe do something along these lines:
That is probably a better option than my suggestion.
(I didn't know about that API)
Last edited on Mar 16, 2020 at 11:14pm UTC
Mar 16, 2020 at 5:38pm UTC
Thanks a lot for the solution, i will try this
Mar 16, 2020 at 7:53pm UTC
md5 is a distinct calculation, so every md5 is the same as any other. If you are annoyed with the need to pass a text string to it, find one that accepts it as a byte-chunk eg digest = md5(char*, size in bytes) instead. Its an annoying, couple of page algorithm, but there are many, many examples of it online. Many are low performance; I had to tweak the one I found a lot.
if yours is in this format, you do not need to do anything at all.
digest = md5( (char *)(&structvar), sizeof(struct)); (it may also want unsigned char* ?? or it may not matter (the bits are the bits))
that may byte you on struct alignments if you are comparing your hash to one generated by someone else using another language or something, but if you can align and pad the bytes the same way, you will get the same digest out, so it may just be compiler flags to align it or something from there.
Last edited on Mar 16, 2020 at 7:56pm UTC
Mar 16, 2020 at 10:43pm UTC
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
typedef unsigned char BYTE;
struct innerprop
{
string a;
string b;
string c;
}
struct prop
{
string id;
string name;
int p;
innerprop ip;
}
int main()
{
BYTE *byte_array = new BYTE[sizeof (prop)];
prop p;
p.id = "hi" ;
p.name = "hehe" ;
p.p = 1542;
p.ip.a = "A" ;
p.ip.b = "B" ;
p.ip.c = "C" ;
memcpy( byte_array, &p, sizeof (prop) );
// use byte_array
// ...
// free allocated memory
delete [] byte_array;
}
if you are not gonna be writing to the byte_array then just
1 2 3
prop p;
BYTE *byte_array = reinterpret_cast <BYTE*>(&p);
// now you can pass byte_array to a function for processing
Last edited on Mar 16, 2020 at 10:50pm UTC
Mar 16, 2020 at 11:11pm UTC
Seems more likely that OP wants to hash the contents of the strings, rather than their object representations.
There is no need to allocate any memory, either.
Last edited on Mar 16, 2020 at 11:13pm UTC
Mar 16, 2020 at 11:34pm UTC
@fewdiefie, I hope you're joking! :)
The data for the strings is (possibly! *) on the heap. All you would be serializing is the pointers and size information.
* small strings (perhaps 8 to 16 bytes) can be stored in the main structure of a string.
If you want to play with the memcpy-the-struct idea and it's problems:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
struct innerprop
{
string a;
string b;
string c;
};
struct prop
{
string id;
string name;
int p;
innerprop ip;
};
void clear( prop& p )
{
#if 0
p.id.clear();
p.name.clear();
p.p = 0;
p.ip.a.clear();
p.ip.b.clear();
p.ip.c.clear();
#else
p.id = "one" ;
p.name = "two" ;
p.p = 123456789;
p.ip.a = "three" ;
p.ip.b = "four" ;
p.ip.c = "five" ;
#endif
}
void prn( prop& p )
{
cout << "======================\n"
<< "id : " << p.id << '\n'
<< "name: " << p.name << '\n'
<< "p : " << p.p << '\n'
<< "ip.a: " << p.ip.a << '\n'
<< "ip.b: " << p.ip.b << '\n'
<< "ip.c: " << p.ip.c << '\n' ;
}
int main()
{
prop p;
#if 0
p.id = "hi" ;
p.name = "hehe" ;
p.p = 1542;
p.ip.a = "Alpha" ;
p.ip.b = "Beta" ;
p.ip.c = "Gamma" ;
#else
p.id = "hiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii" ;
p.name = "hehe" "0123456789012345678901234567890123456789" ;
p.p = 1542;
p.ip.a = "Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ;
p.ip.b = "Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" ;
p.ip.c = "Cccccccccccccccccccccccccccccccccccccccccccccccccccccccc" ;
#endif
prn(p);
auto b = new char [sizeof p];
memcpy( b, &p, sizeof p );
clear(p);
prn(p);
memcpy( &p, b, sizeof p );
prn(p);
delete [] b;
}
Last edited on Mar 17, 2020 at 12:28am UTC
Mar 17, 2020 at 4:44pm UTC
oh, he said char array in the title but used string; mine won't work with string either, of course. Should have looked closer.