1551 Temat założony przez niniejszego użytkownika |
Suma kontrolna CRC-32 » 2017-06-07 13:30:06 Witam.
Mam za zadanie napisać program wyliczający 32-bitowy cykliczny kod nadmiarowy CRC-32 dla dowolnego pliku. Wiem jak wyliczyć CRC "na kartce" stosując XOR'a. Zastanawia mnie jednak jak wyglądać będzie to dla C++, a mianowicie jeżeli zapiszę jakiś tekst np. "system sum kontrolnych wykorzystywany do wykrywania przypadkowych błędów pojawiających się podczas przesyłania i magazynowania danych binarnych" w pliku - w jaki sposób odczytać ten plik(bo chyba nie zapisać tekst do string'a ?), aby był użyteczny przy liczeniu CRC-32 ? Załóżmy, że posiadam wyżej już zapisany tekst w pliku text.txt. Muszę otworzyć plik, jeżeli odczyt się uda to zapisać dane - w stringu chyba nie bardzo będzie mi to użyteczne ? Na koniec mam uzyskać 4 wyniki : CRC-32 w postaci tekstowej jako liczba w systemie dziesiętnym CRC-32 w postaci tekstowej jako liczba w systemie szesnastkowym (8 znaków) CRC-32 w postaci tekstowej jako liczba w systemie dwójkowym (32 znaki „0” lub ”1”) CRC-32 w postaci binarnej (4 bajty 8-bitowe)
Adnotacją jest "w celu wykonania dzielenia przez wielomian należy wykorzystać operacje bitowe".
Mam wykorzystać podstawowy algorytm dzielenia ciągu danych(bajtów 8-bitowych) odczytywanych z zadanego pliku przez wielomian generujący CRC bit po bicie.
Czy ktoś mógłby mi dać jakieś rady i opisać mi, w jaki sposób wczytać dane, aby były użyteczne w liczeniu ? Najlepiej na tym przykładzie, który podałem na górze. Nie chodzi mi o gotowy kod, potrzebuję jedynie pomocy ze zrozumieniem w jaki sposób program ma działać. |
|
pekfos |
» 2017-06-07 16:28:55 Zapomnij, że plik ma jakikolwiek związek z tekstem. Jak się wczytuje dowolny plik..? |
|
1551 Temat założony przez niniejszego użytkownika |
» 2017-06-07 16:39:21 Poprzez operator strumienia wejściowego? Tylko, że w tym przypadku potrzebujemy zmiennej do zapisania danych? Na ten moment zrobiłem coś takiego : int read( string inputname, ifstream & fileread, ofstream & filewrite ) { string newname; bool result; unsigned char byte_8b; fileread.open( inputname.c_str(), ios::binary ); result = fileread.is_open(); if( !result ) { cout << "Blad otwierania pliku odczytywanego w trybie binarnym!" << endl; return - 1; } newname = inputname.substr( 0, inputname.find_last_of( "." ) ) + "_tryb_binarny.txt"; filewrite.open( newname.c_str(), ios::binary ); result = filewrite.is_open(); if( !result ) { cout << "Blad otwierania pliku do zapisu w trybie binarnym!" << endl; return - 2; } while( true ) { byte_8b = fileread.get(); result = fileread.good(); if( !result ) break; filewrite << int( byte_8b ) << " "; cout << int( byte_8b ) << " "; } cout << endl; fileread.close(); filewrite.close(); return 0; }
int main( int argc, char * argv[] ) { string inputname; ifstream fileread; ofstream filewrite; if( argc < 2 ) { cout << "Nie podano nazwy pliku jako parametru wejsciowego!" << endl; return - 1; } inputname = argv[ 1 ]; cout << "Podana nazwa pliku: " << inputname << endl; read( inputname, fileread, filewrite ); system( "Pause" ); return 0; }
Otwieram dany plik w postaci binarnej, pobieram pojedyncze bajty i zapisuję ich wartość decymalną w nowym pliku. Do wykonania zadania potrzebuję binarnej postaci każdego znaku, wczytać je do bufora i wykonać dzielenie przez wielomian generujący ? Nie mam pojęcia jak się za to dalej zabrać ;/ |
|
mateczek |
» 2017-06-07 18:02:44 Do wykonania zadania potrzebuję binarnej postaci każdego znaku |
już w drugim poście dostałeś odpowiedź co masz zrobić!!!! #include <iostream>
using namespace std;
int main() { string s { "abcd " }; int suma = 0; for( char znak: s ) { cout << static_cast < int >( znak ) << endl; suma += znak; } cout << suma << endl; }
|
|
1551 Temat założony przez niniejszego użytkownika |
» 2017-06-07 18:18:45 http://imgur.com/a/hij4Y\ |
|
mateczek |
» 2017-06-07 18:37:29 pewnie nie masz włączonego c++11 tutaj kompilator online https://ideone.com/Q2G2HAA poniżej wycinek z googla gdzie w dev włączyć c++11. Włącz sobie bo to się przydaje i bardzo ułatwia. In Dev C++ 5.2.0.3 it's as simple as go to Tools->Compiler Options->Settings->Code Generation and setting Language standard (-std) to ISO C++11 |
to samo bez c++11 #include <iostream> #include<string> using namespace std;
int main() { string s { "abcd " }; int suma = 0; for( size_t i = 0; i < s.size(); i++ ) { cout << static_cast < int >( s[ i ] ) << endl; suma += s[ i ]; } cout << suma << endl; }
|
|
1551 Temat założony przez niniejszego użytkownika |
» 2017-06-07 18:52:15 Zapomniałem wspomnieć, ale c++11 nie mogę użyć do tego zadania. Zrobiłem na ten moment odczyt znaków z pliku i zapis ich w postaci dziesiętnej w innym pliku.
W jaki sposób mogę teraz te dane przekształcić na wielomian początkowy, a nastepnie podzielić go przez wielomian generujący 0x04C11DB7? Nie mogę również używać "sposobu tablicowego" - "do wyznaczenia CRC-32 należy wykorzystać podstawowy algorytm dzielenia ciągu danych (bajtów 8-bitowych) odczytywanych z zadanego pliku wejściowego przez wielomian generujący CRC bit po bicie."
Przepraszam, że tak opornie to idzie, ale niestety nie mogę tego w żaden sposób załapać. |
|
pekfos |
» 2017-06-07 18:54:49 Czy nie napisałeś przypadkiem na samym początku, że wiesz jak to policzyć? Poprzez operator strumienia wejściowego? |
Nie. Inicjalizacja przez {} to też C++11. |
|
« 1 » 2 3 4 |