效率还行的LZW压缩算法,随机数加密,关键加密方法已经去掉
1 #pragma once 2 3 #include <afxtempl.h> 4 #include "QHashTNBuffer.h" 5 #include "QHashNTBuffer.h" 6 7 class CUtilityLZW 8 { 9 public: 10 CUtilityLZW(void); 11 virtual ~CUtilityLZW(void); 12 13 public: 14 static UINT32 CompressData(PBYTE pUncompressedData, UINT32 nUncompressedLength, CQHashTNBuffer * pListDictionary, CList<UINT32, UINT32> * pListCompressed); 15 static UINT32 UncompressData(CList<UINT32, UINT32> * pListCompressed, CQHashNTBuffer * pListDictionary, PBYTE & pUncompressedData, UINT32 nUncompressedSize); 16 17 public: 18 static UINT32 EncryptData(CList<UINT32, UINT32> * pListCompressed, UINT32 & nOneDataSize, PBYTE & pEncryptData, UINT32 nEncryptSize); 19 static UINT32 DecryptData(PBYTE pEncryptData, UINT32 nEncryptLength, UINT32 nOneDataSize, CList<UINT32, UINT32> * pListCompressed); 20 static UINT32 PackData(PBYTE pEncryptData, UINT32 nEncryptLength, UINT32 nOneDataSize, UINT32 nUncompressedLength, UINT32 nVersionCode, PBYTE & pPackData, UINT32 nPackSize); 21 static UINT32 UnpackData(PBYTE pPackData, UINT32 nPackLength, UINT32 & nOneDataSize, UINT32 & nUncompressedLength, UINT32 & nVersionCode, PBYTE & pEncryptData, UINT32 nEncryptSize); 22 23 public: 24 static UINT32 Compress(PBYTE pUncompressedData, UINT32 nUncompressedLength, PBYTE & pPackData, UINT32 nPackLength); 25 static UINT32 Uncompress(PBYTE pPackData, UINT32 nPackLength, PBYTE & pUncompressedData, UINT32 nUncompressedLength); 26 27 };
1 #include "stdafx.h" 2 #include "UtilityLZW.h" 3 4 #define __PSWX "12324312342345345674567456745674567" 5 6 7 CUtilityLZW::CUtilityLZW(void) 8 { 9 } 10 11 CUtilityLZW::~CUtilityLZW(void) 12 { 13 } 14 15 UINT32 CUtilityLZW::CompressData(PBYTE pUncompressedData, UINT32 nUncompressedLength, CQHashTNBuffer * pListDictionary, CList<UINT32, UINT32> * pListCompressed) 16 { 17 UINT32 nResult = 0; 18 if (pListDictionary == NULL) 19 { 20 pListDictionary = new CQHashTNBuffer(1024); 21 } 22 if (pListDictionary->GetCount() < 256) 23 { 24 for (UINT32 i = 0; i < 256; i++) 25 { 26 BYTE nData = (BYTE)(i); 27 pListDictionary->SetAt((PUINT8)(&nData), 1, i); 28 } 29 } 30 if (pListCompressed == NULL) 31 { 32 pListCompressed = new CList<UINT32, UINT32>(); 33 } 34 CQHashTNNode * pWordKey = new CQHashTNNode(0, 1024); 35 CQHashTNNode * pWordCur = new CQHashTNNode(0, 1024); 36 for (int n = 0; n < nUncompressedLength; n++ ) 37 { 38 BYTE dataCur = pUncompressedData[n]; 39 if (pWordKey->m_nKeyLength > 0) 40 { 41 pWordCur->SetValue(pWordKey->m_pKeyData, pWordKey->m_nKeyLength); 42 } 43 pWordCur->AddTailKey(dataCur); 44 if (pListDictionary->Contains(pWordCur->m_pKeyData, pWordCur->m_nKeyLength)) 45 { 46 pWordKey->SetValue(pWordCur->m_pKeyData, pWordCur->m_nKeyLength); 47 } 48 else 49 { 50 UINT32 nWordValue = 0; 51 if (pListDictionary->Lookup(pWordKey->m_pKeyData, pWordKey->m_nKeyLength, nWordValue)) 52 { 53 pListCompressed->AddTail(nWordValue); 54 } 55 pListDictionary->SetAt(pWordCur->m_pKeyData, pWordCur->m_nKeyLength, pListDictionary->GetCount()); 56 pWordKey->m_nKeyLength = 0; 57 pWordKey->AddTailKey(dataCur); 58 nResult += 1; 59 } 60 } 61 if (pWordKey->m_nKeyLength > 0) 62 { 63 UINT32 nWordValue = 0; 64 if (pListDictionary->Lookup(pWordKey->m_pKeyData, pWordKey->m_nKeyLength, nWordValue)) 65 { 66 pListCompressed->AddTail(nWordValue); 67 } 68 nResult += 1; 69 } 70 if (nResult <= 0) 71 { 72 if (pListDictionary != NULL) 73 { 74 delete pListDictionary; 75 pListDictionary = NULL; 76 } 77 if (pListCompressed != NULL) 78 { 79 delete pListCompressed; 80 pListCompressed = NULL; 81 } 82 } 83 delete pWordKey; 84 delete pWordCur; 85 return nResult; 86 } 87 88 UINT32 CUtilityLZW::UncompressData(CList<UINT32, UINT32> * pListCompressed, CQHashNTBuffer * pListDictionary, PBYTE & pUncompressedData, UINT32 nUncompressedSize) 89 { 90 UINT32 nResult = 0; 91 if (pListDictionary == NULL) 92 { 93 pListDictionary = new CQHashNTBuffer(40960); 94 } 95 if (pListDictionary->GetCount() < 256) 96 { 97 for (UINT32 i = 0; i < 256; i++) 98 { 99 BYTE nData = (BYTE)(i); 100 pListDictionary->SetAt(i, (PUINT8)(&nData), 1); 101 } 102 } 103 if ((pListCompressed != NULL) && (nUncompressedSize > 0)) 104 { 105 if (pListCompressed->GetCount() > 0) 106 { 107 if (pUncompressedData == NULL) 108 { 109 pUncompressedData = new BYTE[nUncompressedSize]; 110 } 111 int wordPos = 0; 112 wordPos = pListCompressed->GetHead(); 113 pListCompressed->RemoveHead(); 114 CQHashNTNode * pWordKey = new CQHashNTNode(0, 0, 256); 115 pListDictionary->Lookup(wordPos, pWordKey); 116 memcpy(pUncompressedData + nResult, pWordKey->m_pValueData, pWordKey->m_nValueLength); 117 nResult += pWordKey->m_nValueLength; 118 CQHashNTNode * pWordEntry = new CQHashNTNode(0, 0, 256); 119 CQHashNTNode * pWordNew = new CQHashNTNode(0, 0, 256); 120 POSITION pos = pListCompressed->GetHeadPosition(); 121 while (pos != NULL) 122 { 123 wordPos = pListCompressed->GetNext(pos); 124 pWordEntry->m_nValueLength = 0; 125 if (pListDictionary->Lookup(wordPos, pWordEntry)) 126 { 127 } 128 else if (wordPos == pListDictionary->GetCount()) 129 { 130 if (pWordKey->m_nValueLength > 0) 131 { 132 pWordEntry->SetValue(wordPos); 133 pWordEntry->SetValue(pWordKey->m_pValueData, pWordKey->m_nValueLength); 134 pWordEntry->AddTailValue(pWordKey->m_pValueData[0]); 135 } 136 } 137 memcpy(pUncompressedData + nResult, pWordEntry->m_pValueData, pWordEntry->m_nValueLength); 138 nResult += pWordEntry->m_nValueLength; 139 if (pWordEntry->m_nValueLength > 0) 140 { 141 UINT32 nNewKey = pListDictionary->GetCount(); 142 pWordNew->m_nValueLength = 0; 143 pWordNew->SetValue(nNewKey); 144 pWordNew->SetValue(pWordKey->m_pValueData, pWordKey->m_nValueLength); 145 pWordNew->AddTailValue(pWordEntry->m_pValueData[0]); 146 pListDictionary->SetAt(nNewKey, pWordNew->m_pValueData, pWordNew->m_nValueLength); 147 } 148 pWordKey->SetValue(pWordEntry->m_nKeyData); 149 pWordKey->SetValue(pWordEntry->m_pValueData, pWordEntry->m_nValueLength); 150 } 151 delete pWordNew; 152 delete pWordEntry; 153 delete pWordKey; 154 } 155 } 156 return nResult; 157 } 158 159 UINT32 CUtilityLZW::EncryptData(CList<UINT32, UINT32> * pListCompressed, UINT32 & nOneDataSize, PBYTE & pEncryptData, UINT32 nEncryptSize) 160 { 161 UINT32 nResult = 0; 162 UINT32 nMaxDatSize = 0; 163 POSITION pos = pListCompressed->GetHeadPosition(); 164 while (pos != NULL) 165 { 166 UINT32 wordPos = pListCompressed->GetNext(pos); 167 if (wordPos <= 0xFF) nMaxDatSize = max(1, nMaxDatSize); 168 else if (wordPos <= 0xFFFF) nMaxDatSize = max(2, nMaxDatSize); 169 else if (wordPos <= 0xFFFFFF) nMaxDatSize = max(3, nMaxDatSize); 170 else if (wordPos <= 0xFFFFFFFF) nMaxDatSize = max(4, nMaxDatSize); 171 else nMaxDatSize = max(4, nMaxDatSize); 172 } 173 nOneDataSize = nMaxDatSize; 174 UINT32 nCompressedLength = nOneDataSize * pListCompressed->GetCount(); 175 if (pEncryptData == NULL) 176 { 177 pEncryptData = new BYTE[nCompressedLength]; 178 } 179 else if (nEncryptSize < nCompressedLength) 180 { 181 delete[] pEncryptData; 182 pEncryptData = new BYTE[nCompressedLength]; 183 } 184 if (nOneDataSize == 1) 185 { 186 POSITION pos = pListCompressed->GetHeadPosition(); 187 while (pos != NULL) 188 { 189 UINT32 wordPos = pListCompressed->GetNext(pos); 190 pEncryptData[nResult++] = (BYTE)(wordPos & 0xFF); 191 } 192 } 193 else if (nOneDataSize == 2) 194 { 195 POSITION pos = pListCompressed->GetHeadPosition(); 196 while (pos != NULL) 197 { 198 UINT32 wordPos = pListCompressed->GetNext(pos); 199 pEncryptData[nResult++] = (BYTE)((wordPos >> 0) & 0xFF); 200 pEncryptData[nResult++] = (BYTE)((wordPos >> 8) & 0xFF); 201 } 202 } 203 else if (nOneDataSize == 3) 204 { 205 POSITION pos = pListCompressed->GetHeadPosition(); 206 while (pos != NULL) 207 { 208 UINT32 wordPos = pListCompressed->GetNext(pos); 209 pEncryptData[nResult++] = (BYTE)((wordPos >> 0) & 0xFF); 210 pEncryptData[nResult++] = (BYTE)((wordPos >> 8) & 0xFF); 211 pEncryptData[nResult++] = (BYTE)((wordPos >> 16) & 0xFF); 212 } 213 } 214 else 215 { 216 POSITION pos = pListCompressed->GetHeadPosition(); 217 while (pos != NULL) 218 { 219 UINT32 wordPos = pListCompressed->GetNext(pos); 220 pEncryptData[nResult++] = (BYTE)((wordPos >> 0) & 0xFF); 221 pEncryptData[nResult++] = (BYTE)((wordPos >> 8) & 0xFF); 222 pEncryptData[nResult++] = (BYTE)((wordPos >> 16) & 0xFF); 223 pEncryptData[nResult++] = (BYTE)((wordPos >> 24) & 0xFF); 224 } 225 } 226 return nResult; 227 } 228 229 UINT32 CUtilityLZW::DecryptData(PBYTE pEncryptData, UINT32 nEncryptLength, UINT32 nOneDataSize, CList<UINT32, UINT32> * pListCompressed) 230 { 231 UINT32 nResult = 0; 232 if (pListCompressed == NULL) 233 { 234 pListCompressed = new CList<UINT32, UINT32>(); 235 } 236 UINT32 nIndex = 0; 237 UINT32 nData = 0; 238 if (nOneDataSize == 1) 239 { 240 while (nIndex < nEncryptLength) 241 { 242 nData = pEncryptData[nIndex++]; 243 pListCompressed->AddTail(nData); 244 nResult += 1; 245 } 246 } 247 else if (nOneDataSize == 2) 248 { 249 while (nIndex < nEncryptLength) 250 { 251 nData = 0; 252 nData |= (((UINT32)pEncryptData[nIndex++]) << 0); 253 nData |= (((UINT32)pEncryptData[nIndex++]) << 8); 254 pListCompressed->AddTail(nData); 255 nResult += 1; 256 } 257 } 258 else if (nOneDataSize == 3) 259 { 260 while (nIndex < nEncryptLength) 261 { 262 nData = 0; 263 nData |= (((UINT32)pEncryptData[nIndex++]) << 0); 264 nData |= (((UINT32)pEncryptData[nIndex++]) << 8); 265 nData |= (((UINT32)pEncryptData[nIndex++]) << 16); 266 pListCompressed->AddTail(nData); 267 nResult += 1; 268 } 269 } 270 else 271 { 272 while (nIndex < nEncryptLength) 273 { 274 nData = 0; 275 nData |= (((UINT32)pEncryptData[nIndex++]) << 0); 276 nData |= (((UINT32)pEncryptData[nIndex++]) << 8); 277 nData |= (((UINT32)pEncryptData[nIndex++]) << 16); 278 nData |= (((UINT32)pEncryptData[nIndex++]) << 24); 279 pListCompressed->AddTail(nData); 280 nResult += 1; 281 } 282 } 283 return nResult; 284 } 285 286 UINT32 CUtilityLZW::PackData(PBYTE pEncryptData, UINT32 nEncryptLength, UINT32 nOneDataSize, UINT32 nUncompressedLength, UINT32 nVersionCode, PBYTE & pPackData, UINT32 nPackSize) 287 { 288 UINT32 nResult = 0; 289 BYTE bKeys[] = { 290 (BYTE)(rand() % 256), (BYTE)(rand() % 256), (BYTE)(rand() % 256), (BYTE)(rand() % 256), 291 (BYTE)(rand() % 256), (BYTE)(rand() % 256), (BYTE)(rand() % 256), (BYTE)(rand() % 256), 292 (BYTE)(rand() % 256), (BYTE)(rand() % 256), (BYTE)(rand() % 256), (BYTE)(rand() % 256), 293 (BYTE)(rand() % 256), (BYTE)(rand() % 256), (BYTE)(rand() % 256), (BYTE)(rand() % 256), 294 }; 295 UINT32 nHeadLen = 32; 296 if ((nEncryptLength > 0) && (pEncryptData != NULL)) 297 { 298 UINT32 nPackLen = nHeadLen + nEncryptLength; 299 if (pPackData != NULL) 300 { 301 if (nPackSize < nPackLen) 302 { 303 delete[] pPackData; 304 pPackData = NULL; 305 } 306 } 307 if (pPackData == NULL) 308 { 309 pPackData = new BYTE[nPackLen]; 310 nPackSize = nPackLen; 311 } 312 UINT32 nData = 0; 313 for (int n = 0; n < 16; n++) 314 { 315 // 这里数据可加密,与随机数运算 316 pPackData[nResult++] = bKeys[n]; 317 } 318 UINT32 nKeyIndex = 0; 319 UINT32 gnData[] = {nVersionCode, nEncryptLength, nOneDataSize, nUncompressedLength }; 320 for (int n = 0; n < 4; n++) 321 { 322 // 这里数据可加密,与随机数运算 323 nData = (BYTE)((gnData[n] >> 0) & 0xFF); 324 pPackData[nResult++] = (BYTE)nData; 325 nData = (BYTE)((gnData[n] >> 8) & 0xFF); 326 pPackData[nResult++] = (BYTE)nData; 327 nData = (BYTE)((gnData[n] >> 16) & 0xFF); 328 pPackData[nResult++] = (BYTE)nData; 329 nData = (BYTE)((gnData[n] >> 24) & 0xFF); 330 pPackData[nResult++] = (BYTE)nData; 331 } 332 for (int n = 0; n < nEncryptLength; n++) 333 { 334 // 这里数据可加密,与随机数运算 335 pPackData[nResult++] = (BYTE)nData; 336 } 337 } 338 return nResult; 339 } 340 341 UINT32 CUtilityLZW::UnpackData(PBYTE pPackData, UINT32 nPackLength, UINT32 & nOneDataSize, UINT32 & nUncompressedLength, UINT32 & nVersionCode, PBYTE & pEncryptData, UINT32 nEncryptSize) 342 { 343 UINT32 nResult = 0; 344 BYTE bKeys[16] = { 0 }; 345 UINT32 nData = 0; 346 UINT32 pos = 0; 347 if (nPackLength > 32) 348 { 349 for (int n = 0; n < 16; n++) 350 { 351 // 这里数据可加密,与随机数运算 352 bKeys[n] = pPackData[pos++]; 353 } 354 UINT32 nKeyIndex = 0; 355 UINT32 gnData[4] = { 0 }; 356 UINT32 nKey = 0; 357 for (int n = 0; n < 4; n++) 358 { 359 // 这里数据可加密,与随机数运算 360 gnData[n] = 0; 361 nData = pPackData[pos++]; 362 gnData[n] |= ((nData & 0xFF) << 0); 363 nData = pPackData[pos++]; 364 gnData[n] |= ((nData & 0xFF) << 8); 365 nData = pPackData[pos++]; 366 gnData[n] |= ((nData & 0xFF) << 16); 367 nData = pPackData[pos++]; 368 gnData[n] |= ((nData & 0xFF) << 24); 369 } 370 UINT32 nEncryptLength = 0; 371 nVersionCode = gnData[0]; 372 nEncryptLength = gnData[1]; 373 nOneDataSize = gnData[2]; 374 nUncompressedLength = gnData[3]; 375 if (pEncryptData == NULL) 376 { 377 nResult += nUncompressedLength; 378 nResult += 32; 379 return nResult; 380 } 381 if (nEncryptSize < nEncryptLength) 382 { 383 delete[] pEncryptData; 384 pEncryptData = NULL; 385 } 386 if (pEncryptData == NULL) 387 { 388 pEncryptData = new BYTE[nEncryptLength]; 389 nEncryptSize = nEncryptLength; 390 } 391 nResult = 0; 392 for (int n = 32; n < nPackLength; n++) 393 { 394 // 这里数据可加密,与随机数运算 395 pEncryptData[nResult++] = ((PBYTE)pPackData)[pos++]; 396 } 397 } 398 return nResult; 399 } 400 401 UINT32 CUtilityLZW::Compress(PBYTE pUncompressedData, UINT32 nUncompressedLength, PBYTE & pPackData, UINT32 nPackSize) 402 { 403 UINT32 nResult = 0; 404 CQHashTNBuffer * pListDictionary = new CQHashTNBuffer(1024); 405 CList<UINT32, UINT32> * pListCompressed = new CList<UINT32, UINT32>(); 406 UINT32 nCompressedCount = CompressData(pUncompressedData, nUncompressedLength, pListDictionary, pListCompressed); 407 if (nCompressedCount > 0) 408 { 409 delete pListDictionary; 410 pListDictionary = NULL; 411 UINT32 nOneDataSize = 0; 412 UINT32 nEncryptLength = 0; 413 PBYTE pEncryptData = NULL; 414 nEncryptLength = EncryptData(pListCompressed, nOneDataSize, pEncryptData, 0); 415 delete pListCompressed; 416 pListCompressed = NULL; 417 if ((nEncryptLength > 0) && (pEncryptData != NULL)) 418 { 419 UINT32 nPackLength = 0; 420 BOOL bDelete = (pPackData == NULL); 421 nPackLength = PackData(pEncryptData, nEncryptLength, nOneDataSize, nUncompressedLength, 0x00F, pPackData, nPackSize); 422 if ((nPackLength > 0) && (pPackData != NULL)) 423 { 424 nResult = nPackLength; 425 } 426 else 427 { 428 if (bDelete && (pPackData != NULL)) 429 { 430 delete[] pPackData; 431 pPackData = NULL; 432 } 433 } 434 } 435 if (pEncryptData != NULL) 436 { 437 delete[] pEncryptData; 438 pEncryptData = NULL; 439 } 440 } 441 if (pListCompressed != NULL) 442 { 443 delete pListCompressed; 444 pListCompressed = NULL; 445 } 446 if (pListDictionary != NULL) 447 { 448 delete pListDictionary; 449 pListDictionary = NULL; 450 } 451 return nResult; 452 } 453 454 UINT32 CUtilityLZW::Uncompress(PBYTE pPackData, UINT32 nPackLength, PBYTE & pUncompressedData, UINT32 nUncompressedSize) 455 { 456 UINT32 nResult = 0; 457 UINT32 nOneDataSize = 0; 458 UINT32 nUncompressedLength = 0; 459 UINT32 nVersionCode = 0; 460 PBYTE pEncryptData = NULL; 461 if (pUncompressedData == NULL) 462 { 463 nResult = UnpackData(pPackData, nPackLength, nOneDataSize, nUncompressedLength, nVersionCode, pEncryptData, 0); 464 return nResult; 465 } 466 UINT32 nEncryptSize = nPackLength * 10; 467 UINT32 nEncryptLength = 0; 468 pEncryptData = new BYTE[nEncryptSize]; 469 nEncryptLength = UnpackData(pPackData, nPackLength, nOneDataSize, nUncompressedLength, nVersionCode, pEncryptData, nEncryptSize); 470 if ((nEncryptLength > 0) && (pEncryptData != NULL)) 471 { 472 CList<UINT32, UINT32> * pListCompressed = new CList<UINT32, UINT32>(); 473 UINT32 nCompressedCount = DecryptData(pEncryptData, nEncryptLength, nOneDataSize, pListCompressed); 474 if (nCompressedCount) 475 { 476 delete[] pEncryptData; 477 pEncryptData = NULL; 478 CQHashNTBuffer * pListDictionary = new CQHashNTBuffer(40960); 479 BOOL bDelete = (pPackData == NULL); 480 if (pUncompressedData != NULL) 481 { 482 if (nUncompressedSize < nUncompressedLength) 483 { 484 delete[] pUncompressedData; 485 pUncompressedData = NULL; 486 } 487 } 488 if (pUncompressedData == NULL) 489 { 490 pUncompressedData = new BYTE[nUncompressedLength]; 491 nUncompressedSize = nUncompressedLength; 492 } 493 nResult = UncompressData(pListCompressed, pListDictionary, pUncompressedData, nUncompressedSize); 494 if (bDelete && (nResult < nUncompressedLength)) 495 { 496 delete[] pUncompressedData; 497 pUncompressedData = NULL; 498 nResult = 0; 499 } 500 delete pListDictionary; 501 pListDictionary = NULL; 502 } 503 delete pListCompressed; 504 pListCompressed = NULL; 505 } 506 if (pEncryptData != NULL) 507 { 508 delete[] pEncryptData; 509 pEncryptData = NULL; 510 } 511 return nResult; 512 }
Demo
1 void CKRTV3BCDemoVCDlg::OnBnClickedButton1() 2 { 3 int n = 0; 4 CStringA strText = " Support for Intel®/Sharp® flash chips Support for AMD/Fujitsu® flash chips Support for ST(Advanced Architecture) flash chips"; 5 6 PBYTE pUncompressedData = new BYTE[1024]; 7 for (int n = 0; n < 1024; n++) 8 { 9 pUncompressedData[n] = (BYTE)(n + rand() % 255); 10 } 11 UINT32 nUncompressedLength = 1024; 12 13 for (int n = 0; n < strText.GetLength(); n++) 14 { 15 pUncompressedData[n] = strText[n]; 16 } 17 nUncompressedLength = strText.GetLength(); 18 19 PBYTE pCompressData = new BYTE[2048]; 20 UINT32 nCompressSize = 2048; 21 UINT32 nCompressLen = CUtilityLZW::Compress(pUncompressedData, nUncompressedLength, pCompressData, nCompressSize); 22 if (nCompressLen > 0) 23 { 24 PBYTE pUncompressData2 = new BYTE[2048]; 25 UINT32 nUncompressSize2 = 2048; 26 UINT32 nUncompressLen2 = CUtilityLZW::Uncompress(pCompressData, nCompressLen, pUncompressData2, nUncompressSize2); 27 if(nUncompressLen2) 28 { 29 n++; 30 } 31 } 32 CString str; 33 str.Format(_T("%d"), n); 34 AfxMessageBox(str); 35 }