Permalänk

CRC32-program

Har knåpat ihop ett litet program för CRC32-checking. Den har stöd för bl a .sfv-filer, för mer info läs Readme.txt.

Skulle uppskatta om Ni kunde testa det lite och kolla ifall ni hittar några bugger eller liknande. Ni får gärna komma med förslag på förbättringar!

Tack på förhand!

http://home.no/burt/crc32_0.1_beta_1.rar

[edit]Ny version:
http://home.no/burt/crc32_0.1_beta_2.rar[/edit]

Updates
-----
-= 0.1 BETA 2 =_
* Now compares two unsigned long CRC32-values instead
of two strings..a bit smarter, yes!

* When reading a file and calculating the CRC32,
instead of reading the whole file at once, the
program now reads 128kb-chunks, so the program
doesn't hog all the memory and makes the computer
slow!

Visa signatur

Aaaaaight! :P

Permalänk
Medlem

Metoden som du använder för att beräkna crc-summan är inte riktigt optimal. Det fungerar inte att allokera lika mycket minne som filen är stor!
Försök bara kolla crc på en fil som är typ 100mb så är det nästintill omöjligt.

Gör istället så att du jobbar med buffrar på säg 8192 bytes eller nått. Sedan gör du så att du läser 8192 bytes från filen kör crc på den, läser in ytterligare 8192 bytes osv osv.

Tycker du ska lösa det problemet omedelbart för som programmet är just nu går det tyvärr inte att använda.

Visa signatur

"Anyone who puts a small gloss on a fundamental technology, calls it proprietary, and then tries to keep others from building on it, is a thief."
-Tim O'Reilly "http://iiice.net/~ice/stuff/secret_msg.wav" - who?

Permalänk
Medlem

Har inte testat det, bara kollat källkoden.

Precis som IcE säger så bör du läsa in en buffer åt gången. Det optimala är att använda 64 KB eller 128 KB stora buffrar, dvs samma buffer som windows använder internt (tror jag).

calcCRC32():
Här öppnar du filen med CreateFile(), för att sedan stänga den och öppna den igen med fopen() ?
Ett tips är att använda FILE_FLAG_SEQUENTIAL_SCAN istället för FILE_FLAG_RANDOM_ACCESS för att snabba upp inläsning.

compareCRC32():
Vore det inte bättre att jämföra DWORD-värden av CRC stället för att omvandla till en string och jämföra med strcmp()...?

Här är ett liten kodsnutt från ett program jag gjorde själv en gång i tiden:

#include <windows.h> #include <tchar.h> #define DO1(buf) crc = CRC32_TAB[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); #define DO2(buf) DO1(buf); DO1(buf); #define DO4(buf) DO2(buf); DO2(buf); #define DO8(buf) DO4(buf); DO4(buf); #define DO16(buf) DO8(buf); DO8(buf); #define CRC_BUFFER_SIZE_ (128*1024) DWORD crc32_file(const _TCHAR * filename) { DWORD crc = 0xFFFFFFFF; DWORD sizelow,sizehigh,dataread,len; HANDLE hFile; unsigned char *buf, *crcbuf; if((hFile=CreateFile(filename,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN,NULL)) != INVALID_HANDLE_VALUE) { sizelow = GetFileSize(hFile,&sizehigh); if( !((sizelow == INVALID_FILE_SIZE) && (GetLastError() != NO_ERROR)) ) { if( !(sizelow == 0 && sizehigh == 0) ) { buf = (unsigned char *)malloc(CRC_BUFFER_SIZE_); do { ReadFile(hFile,buf,CRC_BUFFER_SIZE_,&dataread,NULL); crcbuf = buf; len = dataread; while (len >= 16) { DO16(crcbuf); len -= 16; } if (len) do { DO1(crcbuf); } while (--len); } while(dataread==CRC_BUFFER_SIZE_); free(buf); } } CloseHandle(hFile); } return (~crc); }

Permalänk
Citat:

Ursprungligen inskrivet av IcE
Försök bara kolla crc på en fil som är typ 100mb så är det nästintill omöjligt.

Jag hade inga problem att kolla filer som var 200mb+. Men ska kolla på det där med buffrar. Tackar för tipset!

Visa signatur

Aaaaaight! :P

Permalänk
Citat:

Ursprungligen inskrivet av madah
calcCRC32():
Här öppnar du filen med CreateFile(), för att sedan stänga den och öppna den igen med fopen() ?
Ett tips är att använda FILE_FLAG_SEQUENTIAL_SCAN istället för FILE_FLAG_RANDOM_ACCESS för att snabba upp inläsning.

compareCRC32():
Vore det inte bättre att jämföra DWORD-värden av CRC stället för att omvandla till en string och jämföra med strcmp()...?

Får väl ta och tacka dig med, ska se vad jag kan göra åt de sakerna du/ni påpekat!

Visa signatur

Aaaaaight! :P

Permalänk

Har forskat lite, och borde det inte vara smartare att använda sig av "memory mapping"? Eller är jag helt ute och cyklar?

Visa signatur

Aaaaaight! :P

Permalänk
Medlem

Jag har testat använda MemoryMapping men det visade sig vara en aning slöare än att göra som jag visade med koden ovan.

Om man MM:ar en fil och läser från den, kommer windows endast att läsa in data när det behövs, vilket innebär en del avbrott vid beräkningarna. och inte alls lika snabb "burst-rate".

MM används mycket vid spelprogrammering, där man behöver komma åt data i stora PAK-filer. Genom MM får man direkt åtkomst till fildatan i minnet, om den redan skulle ligga i Windows' filcache.

Annars om man skulle läsa in den från disk (som koden ovan) så måste Windows kopiera filens data från filcachen till programmets minne, vilket tar lite tid.

Sen ska MemoryMapping inte fungera så bra på Win9x men det kan man ju nästan bortse från.

Permalänk

Ja testade att skriva en funktion som använder MM, och upptäckte att det inte alls var så bra.. Så jag har väl inget annat val än att läsa in delar istället..

Visa signatur

Aaaaaight! :P

Permalänk
Glömsk

Har gjort ett SFV-prog jag med. http://psionicist.online.fr/tSFV12.exe

Edit: C givetvis.

Visa signatur

...man is not free unless government is limited. There's a clear cause and effect here that is as neat and predictable as a law of physics: As government expands, liberty contracts.

Permalänk
Medlem

Mitt program ligger här. Kompilerad med unicode så den funkar nog bara i Win2K/XP.

Den kan endast kontrollera, dvs det går inte att skapa sfv med den. Klarar .sfv, .md5 och .par. Även SHA1/SHA2-summor skapade med fsum

Skrivet helt i C med WinAPI-anrop.

Permalänk
Medlem

Snabbast borde vara att läsa nästa block medans man processerar ett annat. Asså, jobba asyncront.

Just nu jobbar programmet så här:

Read
Process
Read
Process
Read
Process
etc.

snabbare att göra:

task1 task2 Read Idle Read Process Read Process Read Process Read Process idle Process

Det går att lösa utan trådar också faktiskt. Läsa ett block, starta en asyncron läsning och sedan processera. Sedan vänta på att asyncrona läsningen är klart och starta ny och sedan processera.

Eller så kan man lösa det med trådar fast det tror jag blir jobbigare.

EDIT: btw, tänk på när ni profilar att filecachen kan förstöra resultaten.

Visa signatur

Teeworlds - För dig som gillar gulliga saker med stora vapen.

Permalänk
Medlem

Finns en artikel här om crc32 och optimering.
http://www.codeproject.com/cpp/crc32.asp?target=crc

Han försökte göra med asyncront dock fick han det inte snabbare än syncront.

Visa signatur

"Anyone who puts a small gloss on a fundamental technology, calls it proprietary, and then tries to keep others from building on it, is a thief."
-Tim O'Reilly "http://iiice.net/~ice/stuff/secret_msg.wav" - who?