程序生成的minidump要debug的话还是比较大的,客户端的需要压缩一下再上传到服务端,不过相对于zlib的话lzma的压缩比更好,所以我选择用lzma.
http://www.7-zip.org/sdk.html
7-zip的多文件打包接口在CPP封装内:ListArchives(加密),DecompressArchives(解密)
轻量级的单文件加解密还是自己封装下简单:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 #pragma once 2 3 #include <vector> 4 #include <xstring> 5 6 class SLzma 7 { 8 public: 9 SLzma(void); 10 ~SLzma(void); 11 12 static int CompressFile(const std::wstring& outfile, const std::wstring& infile, bool is_lzma = true); 13 14 static int UncompressFile(const std::wstring& outfile, const std::wstring& infile, bool is_lzma = true); 15 16 static int CompressInc1(std::vector<unsigned char> &outBuf, const std::vector<unsigned char> &inBuf); 17 18 static int Uncompress1(std::vector<unsigned char> &outBuf, const std::vector<unsigned char> &inBuf); 19 20 static int CompressInc2(std::vector<unsigned char> &outBuf, const std::vector<unsigned char> &inBuf); 21 22 static int Uncompress2(std::vector<unsigned char> &outBuf, const std::vector<unsigned char> &inBuf); 23 24 static unsigned long CompressBuffer(unsigned char *inBuffer, unsigned long inSize, 25 unsigned char *outBuffer, unsigned long outSize, size_t *outSizeProcessed); 26 27 static unsigned long UncompressBuffer(unsigned char *inBuffer, unsigned long inSize, 28 unsigned char *outBuffer, unsigned long outSize, size_t *outSizeProcessed); 29 };
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 #include "stdafx.h" 2 #include "SLzma.h" 3 4 #include <LzmaLib.h> 5 #include <Lzma86.h> 6 #include <LzmaEnc.h> 7 #include <alloc.h> 8 #include <LzmaDec.h> 9 #include <boost/filesystem.hpp> 10 #include <iostream> 11 12 using namespace std; 13 using namespace boost; 14 15 SLzma::SLzma(void) 16 { 17 } 18 19 20 SLzma::~SLzma(void) 21 { 22 } 23 24 static void * AllocForLzma(void *p, size_t size) { return MyAlloc(size); } 25 static void FreeForLzma(void *p, void *address) { MyFree(address); } 26 static ISzAlloc SzAllocForLzma = { &AllocForLzma, &FreeForLzma }; 27 const int FILE_LEN_BUF_SIZE = 8; 28 29 typedef struct 30 { 31 ISeqInStream SeqInStream; 32 const std::vector<unsigned char> *Buf; 33 unsigned BufPos; 34 } VectorInStream; 35 36 SRes VectorInStream_Read(void *p, void *buf, size_t *size) 37 { 38 VectorInStream *ctx = (VectorInStream*)p; 39 *size = min(*size, ctx->Buf->size() - ctx->BufPos); 40 if (*size) 41 memcpy(buf, &(*ctx->Buf)[ctx->BufPos], *size); 42 ctx->BufPos += *size; 43 return SZ_OK; 44 } 45 46 typedef struct 47 { 48 ISeqOutStream SeqOutStream; 49 std::vector<unsigned char> *Buf; 50 } VectorOutStream; 51 52 size_t VectorOutStream_Write(void *p, const void *buf, size_t size) 53 { 54 VectorOutStream *ctx = (VectorOutStream*)p; 55 if (size) 56 { 57 unsigned oldSize = ctx->Buf->size(); 58 ctx->Buf->resize(oldSize + size); 59 memcpy(&(*ctx->Buf)[oldSize], buf, size); 60 } 61 return size; 62 } 63 64 // 65 // 66 67 int SLzma::CompressInc1( 68 std::vector<unsigned char> &outBuf, 69 const std::vector<unsigned char> &inBuf) 70 { 71 unsigned propsSize = LZMA_PROPS_SIZE; 72 unsigned destLen = inBuf.size() + inBuf.size() / 3 + 128; 73 outBuf.resize(propsSize + FILE_LEN_BUF_SIZE + destLen); 74 75 UInt64 filelen = inBuf.size(); 76 for (int i = 0; i < FILE_LEN_BUF_SIZE; i++) 77 { 78 Byte b = Byte(filelen >> (FILE_LEN_BUF_SIZE * i)); 79 outBuf[LZMA_PROPS_SIZE+i] = b; 80 } 81 82 int res = LzmaCompress( 83 &outBuf[LZMA_PROPS_SIZE+FILE_LEN_BUF_SIZE], &destLen, 84 &inBuf[0], inBuf.size(), 85 &outBuf[0], &propsSize, 86 5, /* 0 <= level <= 9, default = 5 */ 87 (1 << 24), /* default = (1 << 24) */ 88 3, /* 0 <= lc <= 8, default = 3 */ 89 0, /* 0 <= lp <= 4, default = 0 */ 90 2, /* 0 <= pb <= 4, default = 2 */ 91 32, /* 5 <= fb <= 273, default = 32 */ 92 2 /* 1 or 2, default = 2 */ 93 ); 94 95 if(res == SZ_OK) 96 outBuf.resize(propsSize + 8 + destLen); 97 98 return res; 99 } 100 101 int SLzma::Uncompress1( 102 std::vector<unsigned char> &outBuf, 103 const std::vector<unsigned char> &inBuf) 104 { 105 UInt64 fileSize = 0; 106 for (int i = 0; i < FILE_LEN_BUF_SIZE; i++) 107 { 108 unsigned char b = inBuf[LZMA_PROPS_SIZE + i]; 109 fileSize += (b) << (i * FILE_LEN_BUF_SIZE); 110 } 111 112 outBuf.resize(fileSize); 113 unsigned dstLen = outBuf.size(); 114 unsigned srcLen = inBuf.size() - LZMA_PROPS_SIZE - FILE_LEN_BUF_SIZE; 115 SRes res = LzmaUncompress( 116 &outBuf[0], &dstLen, 117 &inBuf[LZMA_PROPS_SIZE+FILE_LEN_BUF_SIZE], &srcLen, 118 &inBuf[0], LZMA_PROPS_SIZE); 119 if(res == SZ_OK); 120 outBuf.resize(dstLen); // If uncompressed data can be smaller 121 return res; 122 } 123 124 // 125 // 126 int SLzma::CompressInc2( 127 std::vector<unsigned char> &outBuf, 128 const std::vector<unsigned char> &inBuf) 129 { 130 CLzmaEncHandle enc = LzmaEnc_Create(&SzAllocForLzma); 131 if(!enc) return -1; 132 133 CLzmaEncProps props; 134 LzmaEncProps_Init(&props); 135 props.writeEndMark = 1; // 0 or 1 136 137 SRes res = LzmaEnc_SetProps(enc, &props); 138 if(res != SZ_OK) return res; 139 140 unsigned propsSize = LZMA_PROPS_SIZE+8; 141 outBuf.resize(propsSize); 142 143 res = LzmaEnc_WriteProperties(enc, &outBuf[0], &propsSize); 144 if(res != SZ_OK || propsSize != LZMA_PROPS_SIZE) return -1; 145 146 UInt64 filelen = inBuf.size(); 147 for (int i = 0; i < FILE_LEN_BUF_SIZE; i++) 148 { 149 Byte b = Byte(filelen >> (FILE_LEN_BUF_SIZE * i)); 150 outBuf[LZMA_PROPS_SIZE+i] = b; 151 } 152 153 VectorInStream inStream = { &VectorInStream_Read, &inBuf, 0 }; 154 VectorOutStream outStream = { &VectorOutStream_Write, &outBuf }; 155 156 res = LzmaEnc_Encode(enc, 157 (ISeqOutStream*)&outStream, (ISeqInStream*)&inStream, 158 0, &SzAllocForLzma, &SzAllocForLzma); 159 160 LzmaEnc_Destroy(enc, &SzAllocForLzma, &SzAllocForLzma); 161 162 return res; 163 } 164 165 int SLzma::Uncompress2( 166 std::vector<unsigned char> &outBuf, 167 const std::vector<unsigned char> &inBuf) 168 { 169 CLzmaDec dec; 170 LzmaDec_Construct(&dec); 171 172 SRes res = LzmaDec_Allocate(&dec, &inBuf[0], LZMA_PROPS_SIZE, &SzAllocForLzma); 173 if(res != SZ_OK) 174 return res; 175 176 LzmaDec_Init(&dec); 177 178 UInt64 fileSize = 0; 179 for (int i = 0; i < FILE_LEN_BUF_SIZE; i++) 180 { 181 unsigned char b = inBuf[LZMA_PROPS_SIZE + i]; 182 fileSize += (b) << (i * FILE_LEN_BUF_SIZE); 183 } 184 185 outBuf.resize(fileSize); 186 unsigned outPos = 0, inPos = LZMA_PROPS_SIZE+FILE_LEN_BUF_SIZE; 187 ELzmaStatus status; 188 const unsigned BUF_SIZE = 10240; 189 while (outPos < outBuf.size()) 190 { 191 unsigned destLen = min(BUF_SIZE, outBuf.size() - outPos); 192 unsigned srcLen = min(BUF_SIZE, inBuf.size() - inPos); 193 unsigned srcLenOld = srcLen, destLenOld = destLen; 194 res = LzmaDec_DecodeToBuf(&dec, 195 &outBuf[outPos], &destLen, 196 &inBuf[inPos], &srcLen, 197 (outPos + destLen == outBuf.size()) 198 ? LZMA_FINISH_END : LZMA_FINISH_ANY, &status); 199 if(res != SZ_OK) 200 break; 201 inPos += srcLen; 202 outPos += destLen; 203 if (status == LZMA_STATUS_FINISHED_WITH_MARK) 204 break; 205 } 206 207 LzmaDec_Free(&dec, &SzAllocForLzma); 208 outBuf.resize(outPos); 209 210 return res; 211 } 212 213 // 214 // 215 unsigned long SLzma::CompressBuffer(unsigned char *inBuffer, unsigned long inSize, 216 unsigned char *outBuffer, unsigned long outSize, size_t *outSizeProcessed) 217 { 218 bool dictDefined = false; 219 UInt32 dict = (UInt32)-1; 220 221 if ((inSize == 0) || (inBuffer == 0)) return 1; 222 if (/*(outSize == 0) || */(outBuffer == 0)) return 1; 223 224 Byte *outBuffer2 = 0; 225 size_t outSize2; 226 227 // we allocate 105% of original size for output buffer 228 outSize2 = (size_t)inSize / 20 * 21 + (1 << 16); //fileSize / 20 * 21 + (1 << 16) 229 if (outSize2 != 0) 230 { 231 outBuffer2 = (Byte *)MyAlloc((size_t)outSize2); 232 if (outBuffer2 == 0) return 1;//throw "Can not allocate memory"; 233 } 234 235 if (!dictDefined) dict = 1 << 23; 236 237 *outSizeProcessed = outSize2; // !! 238 int res = Lzma86_Encode(outBuffer2, outSizeProcessed, inBuffer, inSize, 239 5, dict, SZ_FILTER_AUTO); 240 if (res != 0) 241 { 242 // Encoder error = (int)res 243 return 1; 244 } 245 246 memcpy(outBuffer, outBuffer2, *outSizeProcessed); 247 248 MyFree(outBuffer2); 249 250 return *outSizeProcessed == 0 ?1:0; 251 } 252 253 unsigned long SLzma::UncompressBuffer(unsigned char *inBuffer, unsigned long inSize, 254 unsigned char *outBuffer, unsigned long outSize, size_t *outSizeProcessed) 255 { 256 if ((inSize == 0) || (inBuffer == 0)) return 1; 257 if (/*(outSize == 0) || */(outBuffer == 0)) return 1; 258 259 Byte *outBuffer2 = 0; 260 size_t outSize2; 261 262 UInt64 outSize64; 263 if (Lzma86_GetUnpackSize(inBuffer, inSize, &outSize64) != 0) 264 return 1;//throw "data error"; 265 outSize2 = (size_t)outSize64; 266 if (outSize2 != outSize64) 267 return 1;//throw "too big"; 268 if (outSize2 != 0) 269 { 270 outBuffer2 = (Byte *)MyAlloc(outSize2); 271 if (outBuffer2 == 0) 272 return 1;//throw "Can not allocate memory"; 273 } 274 275 size_t inSize2 = inSize; 276 *outSizeProcessed = outSize2; 277 int res = Lzma86_Decode(outBuffer2, outSizeProcessed, inBuffer, &inSize2); 278 if (inSize2 != (size_t)inSize) 279 return 1;//throw "incorrect processed size"; 280 if (res != 0) 281 return 1;//throw "LzmaDecoder error"; 282 283 memcpy(outBuffer, outBuffer2, *outSizeProcessed); 284 285 MyFree(outBuffer2); 286 287 return *outSizeProcessed == 0 ?1:0; 288 } 289 290 // 291 // 292 int SLzma::CompressFile(const std::wstring& outfile, const std::wstring& infile, bool is_lzma) 293 { 294 295 filesystem::path pt(infile); 296 size_t srclen = filesystem::file_size(pt); 297 298 ifstream inputStream(infile.c_str(),ios::ios_base::binary |ios::ios_base::in); 299 300 vector<UCHAR> intbuf; 301 if(inputStream.fail() || srclen <= 0) 302 { 303 inputStream.clear(); 304 inputStream.close(); 305 return -1; 306 } 307 else 308 { 309 intbuf.resize(srclen); 310 int readBytes = 0; 311 312 while(!inputStream.eof() && readBytes < srclen) 313 { 314 inputStream.read((char*)&intbuf[readBytes],srclen - readBytes); 315 if (inputStream.fail()) 316 { 317 break; 318 } 319 readBytes += inputStream.gcount(); 320 } 321 322 inputStream.clear(); 323 inputStream.close(); 324 } 325 326 vector<UCHAR> outbuf; 327 int result = 0; 328 if(is_lzma) 329 result = SLzma::CompressInc1(outbuf, intbuf); 330 else 331 result = SLzma::CompressInc2(outbuf, intbuf); 332 if (0 == result) 333 { 334 ofstream outfile(outfile.c_str(), ios::ios_base::binary |ios::ios_base::out); 335 if(!outfile.fail()) 336 { 337 outfile.write((const char*)outbuf.data(), outbuf.size()); 338 outfile.flush(); 339 outfile.clear(); 340 outfile.close(); 341 } 342 } 343 return result; 344 } 345 346 347 int SLzma::UncompressFile(const std::wstring& outfile, const std::wstring& infile, bool is_lzma) 348 { 349 350 filesystem::path pt(infile); 351 size_t srclen = filesystem::file_size(pt); 352 353 ifstream inputStream(infile.c_str(),ios::ios_base::binary |ios::ios_base::in); 354 355 vector<UCHAR> intbuf; 356 if(inputStream.fail() || srclen <= 0) 357 { 358 inputStream.clear(); 359 inputStream.close(); 360 return -1; 361 } 362 else 363 { 364 intbuf.resize(srclen); 365 int readBytes = 0; 366 367 while(!inputStream.eof() && readBytes < srclen) 368 { 369 inputStream.read((char*)&intbuf[readBytes],srclen - readBytes); 370 if (inputStream.fail()) 371 { 372 break; 373 } 374 readBytes += inputStream.gcount(); 375 } 376 377 inputStream.clear(); 378 inputStream.close(); 379 } 380 381 vector<UCHAR> outbuf; 382 int result = 0; 383 if(is_lzma) 384 result = SLzma::Uncompress1(outbuf, intbuf); 385 else 386 result = SLzma::Uncompress2(outbuf, intbuf); 387 if (0 == result) 388 { 389 ofstream outfile(outfile.c_str(), ios::ios_base::binary |ios::ios_base::out); 390 if(!outfile.fail()) 391 { 392 outfile.write((const char*)outbuf.data(), outbuf.size()); 393 outfile.flush(); 394 outfile.clear(); 395 outfile.close(); 396 } 397 } 398 return result; 399 }