// make a difference file from two saved games void DIFF_Diff_t(CTStream *pstrmOld, CTStream *pstrmNew, CTStream *pstrmDiff) { try { CTimerValue tv0 = _pTimer->GetHighPrecisionTimer(); _slSizeOld = pstrmOld->GetStreamSize()-pstrmOld->GetPos_t(); _pubOld = (UBYTE*)AllocMemory(_slSizeOld); pstrmOld->Read_t(_pubOld, _slSizeOld); _slSizeNew = pstrmNew->GetStreamSize()-pstrmNew->GetPos_t(); _pubNew = (UBYTE*)AllocMemory(_slSizeNew); pstrmNew->Read_t(_pubNew, _slSizeNew); CRC_Start(_ulCRC); CRC_AddBlock(_ulCRC, _pubNew, _slSizeNew); CRC_Finish(_ulCRC); _pstrmOut = pstrmDiff; MakeDiff_t(); CTimerValue tv1 = _pTimer->GetHighPrecisionTimer(); //CPrintF("diff encoded in %.2gs\n", (tv1-tv0).GetSeconds()); Cleanup(); } catch (char *) { Cleanup(); throw; } }
// dump checksums for all files from the list ULONG CRCT_MakeCRCForFiles_t(CTStream &strmFiles) // throw char * { BOOL bOld = CRCT_bGatherCRCs; CRCT_bGatherCRCs = TRUE; ULONG ulCRC; CRC_Start(ulCRC); // read number of active files INDEX ctFiles; strmFiles>>ctFiles; // for each one for(INDEX i=0; i<ctFiles; i++) { // read the name CTString strName; strmFiles>>strName; CTFileName fname = strName; // try to find it in table CCRCEntry *pce = _ntEntries.Find(fname); // if not there if (pce==NULL) { CRCT_AddFile_t(fname); // add it now pce = _ntEntries.Find(fname); } // add the crc CRC_AddLONG(ulCRC, pce->ce_ulCRC); } CRCT_bGatherCRCs = bOld; CRC_Finish(ulCRC); return ulCRC; }
/* Get CRC32 of stream */ ULONG CTStream::GetStreamCRC32_t(void) { // remember where stream is now SLONG slOldPos = GetPos_t(); // go to start of file SetPos_t(0); // get size of file SLONG slFileSize = GetStreamSize(); ULONG ulCRC; CRC_Start(ulCRC); // for each block in file const SLONG slBlockSize = 4096; for(SLONG slPos=0; slPos<slFileSize; slPos+=slBlockSize) { // read the block UBYTE aubBlock[slBlockSize]; SLONG slThisBlockSize = Min(slFileSize-slPos, slBlockSize); Read_t(aubBlock, slThisBlockSize); // checksum it CRC_AddBlock(ulCRC, aubBlock, slThisBlockSize); } // restore position SetPos_t(slOldPos); CRC_Finish(ulCRC); return ulCRC; }
int main(void) { int i, j; unsigned short CRC_Xmit; unsigned short CRC_Recv; int Detected_Count = 0; int Okay_Count = 0; /* Initialize. */ for (i = 0; i < 1024; i++) { Raw_Data[i] = (unsigned char)i; } CRC_Xmit = CRC_Clear(); Initialize_Noise(1.0e-5); /* Compute the CRC checksum. */ for (i = 0; i < 1024; i++) { CRC_Xmit = CRC_Update(CRC_Xmit, Raw_Data[i]); } CRC_Xmit = CRC_Finish(CRC_Xmit); /* Now loop many times sending the block of data through the channel. */ for (i = 0; i < 1024; i++) { CRC_Recv = CRC_Clear(); for (j = 0; j < 1024; j++) { CRC_Recv = CRC_Update(CRC_Recv, Channel(Raw_Data[j])); } CRC_Recv = CRC_Update(CRC_Recv, Channel((CRC_Xmit & 0xFF00) >> 8)); CRC_Recv = CRC_Update(CRC_Recv, Channel(CRC_Xmit & 0x00FF)); if (CRC_Recv != 0) Detected_Count++; else Okay_Count++; } printf("Blocks with detected errors: %d\n", Detected_Count); printf("Blocks okay: %d\n", Okay_Count); return 0; }
void UnDiff_t(void) { // start at beginning UBYTE *pubOld = _pubOld; UBYTE *pubNew = _pubNew; SLONG slSizeOldStream = 0; SLONG slSizeOutStream = 0; // get header with size of files if (*(SLONG*)pubNew!=DIFF) { ThrowF_t(TRANS("Not a DIFF stream!")); } pubNew+=sizeof(SLONG); slSizeOldStream = *(SLONG*)pubNew; pubNew+=sizeof(SLONG); slSizeOutStream = *(SLONG*)pubNew; pubNew+=sizeof(SLONG); ULONG ulCRC = *(ULONG*)pubNew; pubNew+=sizeof(ULONG); CRC_Start(_ulCRC); if (slSizeOldStream!=_slSizeOld) { ThrowF_t(TRANS("Invalid DIFF stream!")); } // while not end of diff file while (pubNew<_pubNew+_slSizeNew) { // read block type UBYTE ubType = *(pubNew++); switch(ubType) { // if block type is 'copy from old file' case DIFF_OLD: { // get data offset and size SLONG slOffsetOld = *(SLONG*)pubNew; pubNew+=sizeof(SLONG); SLONG slSizeOld = *(SLONG*)pubNew; pubNew+=sizeof(SLONG); // copy it from there (*_pstrmOut).Write_t(_pubOld+slOffsetOld, slSizeOld); CRC_AddBlock(_ulCRC, _pubOld+slOffsetOld, slSizeOld); } break; // if block type is 'copy from new file' case DIFF_NEW: { // get data size SLONG slSizeNew = *(SLONG*)pubNew; pubNew+=sizeof(SLONG); // copy it from there (*_pstrmOut).Write_t(pubNew, slSizeNew); CRC_AddBlock(_ulCRC, pubNew, slSizeNew); pubNew+=slSizeNew; } break; // if block type is 'xor between an old block and a new block' case DIFF_XOR: { // get data offset and sizes SLONG slOffsetOld = *(SLONG*)pubNew; pubNew+=sizeof(SLONG); SLONG slSizeOld = *(SLONG*)pubNew; pubNew+=sizeof(SLONG); SLONG slSizeNew = *(SLONG*)pubNew; pubNew+=sizeof(SLONG); // xor it SLONG slSizeXor = Min(slSizeOld, slSizeNew); UBYTE *pub0 = _pubOld+slOffsetOld; UBYTE *pub1 = pubNew; for (INDEX i=0; i<slSizeXor; i++) { *(pub1++) ^= *(pub0++); } // copy the xor-ed data (*_pstrmOut).Write_t(pubNew, slSizeNew); CRC_AddBlock(_ulCRC, pubNew, slSizeNew); pubNew+=slSizeNew; } break; default: ThrowF_t(TRANS("Invalid DIFF block type!")); } } CRC_Finish(_ulCRC); //printf("CRC is (%lu), expected (%lu).\n", _ulCRC, ulCRC); if (_ulCRC!=ulCRC) { ThrowF_t(TRANS("CRC error in DIFF!")); } }