对stl字符串和其他容器进行加密和序列化



我在stl容器(向量)中有数据。向量中的每个节点都是一个结构,该结构还包含stl字符串。

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

我想序列化员工,但也希望在序列化之前对其进行加密。

我的加密函数如下:

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

通过搜索,stl标准似乎不要求我的结构的内存是连续的,所以我不能只获取employees变量的内存。有没有其他聪明的方法可以让我在基于stl的结构/容器中使用这个编码函数?Encode函数在纯char*缓冲区中工作对我来说很好,所以我确切地知道进出的内容,但stl结构不是,我正在寻找一种很好的方法,这样我就可以将stl与这个函数一起使用。

如果有帮助的话,我也愿意使用任何其他stl容器。

尽管std::vector<T>中的元素保证连续排列,但这并没有真正的帮助:您拥有的记录可能包括填充,更重要的是,将在std::string对象外部存储std::string的内容(在使用小字符串优化的情况下,该值可能嵌入std::string内部,但它也将包含不属于std::string值的几个字节)。因此,您最好的选择是格式化您的记录并加密格式化的字符串。

格式化是直接的,但就我个人而言,我会将编码函数封装到一个简单的std::streambuf中,以便可以通过过滤流缓冲区进行加密。考虑到你给出的签名,这可能看起来像这样:

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 outputn" << std::flush;
}

现在,为只打印到std::ostream的记录创建一个输出操作符可以用来创建一个编码的

将结构序列化为字符串,然后加密字符串可能是最简单的方法。例如:

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

如果是我,我可能会编写encode(或者至少是它的包装器),以获取向量、字符串或流中的输入(并可能产生输出)。

如果你想雄心勃勃,还有其他的可能性。首先,@MooingDuck提出了一个很好的观点,即为类重载operator<<通常是值得的,而不是一直处理单个项目。这通常是一个类似于上面的小功能:

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

使用这个,你只需要:

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

其次,如果你想真正雄心勃勃,你可以将加密放入(例如)codecvt方面,这样你就可以在将所有数据写入流时自动加密,并在读回流时解密。另一种可能性是将加密构建到过滤streambuf对象中。codecvt方面可能是理论上应该首选的方法,但streambuf几乎可以肯定更容易实现,所涉及的不相关的"东西"更少。

最新更新