Encrypt and serialize stl string and other containers

I have data in stl containers (vector). Each node in the vector is a structure that also contains stl lines.

struct record { string name; string location; int salary; } vector< record > employees; 

I want to serialize employees, but I also want to encrypt them before serialization.

my encryption function looks like this:

 Encode(const char * inBfr, const int in_size, char ** outBfr, int& out_size ) 

When searching, it looks like this: stl standard does not require the memory of my structure to be contiguous, so I canโ€™t just grab the memory of the employees variable. Is there any other smart way that I can use this encoding function with my stl structures / containers? It is good for me that the Encode function works in regular char * buffers, so I know exactly what happens and comes out, but there are no stl structures, and I'm trying to find a good way, so I can use stl with this function.

I also open any other stl containers for use if that helps.

+4
source share
2 answers

Despite the fact that the element in std::vector<T> guaranteed to be aligned adjacent, this will not help: the record you can include includes an addition and, more importantly, it will keep the contents of std::string external to to std::string (in the case of optimizing small strings, the value can be embedded inside std::string , but it will also contain a couple of bytes that are not part of the value of std::string ). Thus, the best option is to format your record and encrypt the formatted string.

The formatting is straightforward, but personally I would encapsulate the encoding function in a simple std::streambuf so that encryption can be performed by the filter stream buffer. Given the signature you gave, it might look something like this:

 class encryptbuf : public std::streambuf { std::streambuf* d_sbuf; char d_buffer[1024]; public: encryptbuf(std::streambuf* sbuf) : d_sbuf(sbuf) { this->setp(this->d_buffer, this->d_buffer + sizeof(this->d_buffer) - 1); } int overflow(int c) { if (c != std::char_traits<char>::eof()) { *this->pptr() = std::char_traits<char>::to_char_type(c); this->pbump(1); } return this->pubsync()? std::char_traits<char>::eof(): std::char_traits<char>::not_eof(c); } int sync() { char* out(0); int size(0); Encode(this->pbase(), this->pptr() - this->pbase(), &out, size); this->d_sbuf->sputn(out, size); delete[] out; // dunno: it seems the output buffer is allocated but how? this->setp(this->pbase(), this->epptr()); return this->d_sbuf->pubsync(); } }; int main() { encryptbuf sbuf(std::cout.rdbuf()); std::ostream eout(&sbuf); eout << "print something encoded to standard output\n" << std::flush; } 

Now creating an output statement for your records, only for printing on std::ostream , can be used to create encoded

+12
source

Perhaps the easiest way is to serialize your structure into a string and then encrypt the string. For instance:

 std::ostringstream buffer; buffer << a_record.name << "\n" << a_record.location << "\n" << a_record.salary; encode(buffer.str().c_str(), buffer.str().length(), /* ... */); 

If it were me, I would probably write encode (or at least a wrapper for it) to accept input (and probably produce output) into a vector, string or stream.

If you want ambitiously, there are other possibilities. First of all, @MooingDuck raises a good point that it is often worth overloading operator<< for a class, rather than working with individual elements all the time. Usually this will be a small function similar to the one described above:

 std::ostream &operator<<(std::ostream &os, record const &r) { return os << r.name << "\n" << r.location << "\n" << r.salary; } 

Using this, you simply have:

 std::ostringstream os; os << a_record; encode(os.str().c_str(), os.str().length(), /* ... */); 

Secondly, if you want to become very ambitious, you can put encryption in (for example) the codecvt facet codecvt that you can automatically encrypt all data when writing to the stream and decrypt it as you read it again. Another possibility is to instead encrypt to the streambuf filtering streambuf . The codecvt is probably a method that should theoretically be preferred, but streambuf almost certainly easier to implement, with less unrelated โ€œstuffโ€ involved.

+6
source

Source: https://habr.com/ru/post/1437681/


All Articles