Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Suma kontrolna CRC-32

Ostatnio zmodyfikowano 2017-06-17 18:30
Autor Wiadomość
1551
Temat założony przez niniejszego użytkownika
» 2017-06-07 18:56:14
Wiem jak to policzyć "na kartce". Nie wiem jednak w jaki sposób to zaimplementować.
P-162208
1551
Temat założony przez niniejszego użytkownika
» 2017-06-07 21:38:19
Mam aktualnie coś takiego :
C/C++
#include<cstdlib>
#include<string>
#include<iostream>
#include<fstream>

using namespace std;
int read( string inputname, ifstream & fileread, ofstream & filewrite );

/*int read(string inputname, ifstream &fileread, ofstream &filewrite)
{

string newname, text;
bool result;

fileread.open(inputname.c_str());

    result=fileread.is_open();
if (!result)
{
cout << "Blad otwierania pliku odczytywanego w trybie tekstowym!" << endl;
return -1;
}

inputname.erase(inputname.find_last_of("."), inputname.length());
newname = inputname + "TEST.txt";

filewrite.open(newname.c_str());

result=filewrite.is_open();
if (!result)
{
cout << "Blad otwierania pliku do zapisu w trybie tekstowym!" << endl;
return -2;
}


while (true)
{

fileread >> text;


result=fileread.good();
if (!result) break;


filewrite << text << endl;


cout << text << endl;

}


fileread.close();


//filewrite.close();

return 0;
}*/

void dec_to_bin( int liczba, ofstream & filewrite )
{
    int i = 0, tab[ 31 ];
   
    while( liczba )
    {
        tab[ i++ ] = liczba % 2;
        liczba /= 2;
    }
   
    for( int j = i - 1; j >= 0; j-- )
    {
        filewrite << tab[ j ];
    }
}

void dec_to_binarray( int liczba, int array[] )
{
    int i = 0, tab[ 31 ];
   
    while( liczba )
    {
        tab[ i++ ] = liczba % 2;
        liczba /= 2;
    }
   
    for( int j = i - 1; j >= 0; j-- )
    {
        array[ j ] = tab[ j ];
    }
}

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)<< " ";
        dec_to_bin( byte_8b, filewrite ); filewrite << " ";
        cout << /*int(byte_8b) << */ " ";
    }
   
    cout << endl;
   
   
    fileread.close();
   
   
    filewrite.close();
   
    return 0;
}





int main( int argc, char * argv[] )
{
    string inputname;
    ifstream fileread;
    ofstream filewrite;
    int array[ 32 ] = { 0 };
    int arrayreversed[ 31 ] = { 0 };
   
    if( argc < 2 )
    {
        cout << "Nie podano nazwy pliku jako parametru wejsciowego!" << endl;
        return - 1;
    }
   
    inputname = argv[ 1 ];
   
    cout << "\n Podana nazwa pliku: " << inputname << endl;
   
    read( inputname, fileread, filewrite );
   
    cout << "\n Wielomian generujacy ma postac : 0x04C11DB7";
   
   
    int generator = strtol( "04C11DB7", 0, 16 );
   
    cout << "\n Decymalna postac wielomianu generujacego : " << generator;
   
    dec_to_binarray( generator, array );
   
   
    for( int i = 0; i < 32; i++ )
    {
        arrayreversed[ 31 - i ] = array[ i ];
    }
    cout << "\n\n Binarna postac wielomianu generujacego : \n ";
    for( int i = 0; i < 32; i++ )
    {
        cout << arrayreversed[ i ] << " ";
    }
   
    cout << endl << endl;
   
    system( "Pause" );
    return 0;
}

Wczytuję dane z pliku tekstowego i konwertuję je na postać binarną. W jaki sposób wczytać teraz każde 8 bitów znaku do jednej tablicy, aby móc wykonać dzielenie przez wielomian generujący ?

Wczytując plik z tekstem : Witaj5 otrzymam w nowym pliku : 1010111 1101001 1110100 1100001 1101010 110101.

W jaki sposób mogę z nowego pliku wczytać wszystkie znaki do nowej tablicy, którą później będę dzielił przez wielomian generujący?

Oraz czy ktoś mógłby mi poprawić kod, aby do pliku zapisywał ciągi 8-bitowe ? Bo aktualnie pomija zera na początku.
P-162219
pekfos
» 2017-06-07 23:08:05
Aktualnie to to jest niezgodne z treścią zadania. Skoro masz używać operacji bitowych, program ma nie rozdzielać bajtów na niezależne bity. Bity, siłą rzeczy, są w bajcie i to ma wystarczyć.
P-162221
1551
Temat założony przez niniejszego użytkownika
» 2017-06-07 23:24:28
Czyli jeżeli mam tekst "Witaj" to powinien wykonywać operacje na każdym bajcie tak ? Czyli działać na W,i,t,a,j oddzielnie a nie na ich binarnych odpowiednikach ?
P-162222
1551
Temat założony przez niniejszego użytkownika
» 2017-06-08 00:06:38
Znalazłem coś takiego :
C/C++
//Michal Knasiecki
//www.algorytm.org

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>

//Wielomian dla CRC-32 zgodny ze standardem Ethernet, ZIP i RAR
#define P 0x04c11db7


unsigned long tablica[ 256 ];

//Funkcja zamienia miejscami bity starsze z mlodszymi
unsigned long Zamien_bity( unsigned long liczba, char l_bitow )
{
    unsigned long wynik = 0;
    for( int i = 1; i <( l_bitow + 1 ); i++ )
    {
        if( liczba & 1 )
             wynik |= 1 <<( l_bitow - i );
       
        liczba >>= 1;
    }
    return wynik;
}

//Wypelnia tablice odpowiednimi wartosciami
void Inicjuj_tablice( void ) {
    //Dla kazdego znaku ASCII
    for( int ASCII = 0; ASCII < 256; ASCII++ )
    {
        tablica[ ASCII ] = Zamien_bity( ASCII, 8 ) << 24;
        for( int j = 0; j < 8; j++ )
        {
            if(( tablica[ ASCII ] &( 1 << 31 ) ) != 0 )
            tablica[ ASCII ] =( tablica[ ASCII ] << 1 ) ^ P; else
            tablica[ ASCII ] =( tablica[ ASCII ] << 1 );
        }
        tablica[ ASCII ] = Zamien_bity( tablica[ ASCII ], 32 );
    }
    return;
}

void Oblicz_CRC( char * txt ) {
    //Wartosc poczatkowa to (2^32)-1
    unsigned long crc32 = 0xffffffff;
   
    int wynik;
    char kod[ 20 ];
   
    //Liczba bajtow do przetworzenia
    int dlugosc;
   
    //Tekst, dla ktorego obliczymy crc32
    unsigned char * tekst;
    //------------------------------------------------------------
   
    //Przykladowy tekst
    tekst =( unsigned char * ) txt;
    dlugosc = strlen( tekst );
   
    //Obliczaj crc przesuwajac kolejne znaki tekstu wejsciowego
    while( dlugosc-- )
         crc32 =( crc32 >> 8 ) ^ tablica[( crc32 & 255 ) ^* tekst++ ];
    //Wykonaj operacje XOR z wartoscia poczatkowa
    wynik = crc32 ^ 0xffffffff;
   
    //Zamien wynik na hex
    itoa( wynik, kod, 16 );
    printf( "Tekst wejsciowy: %s\n", txt );
    printf( "Suma CRC32: %s\n", kod );
    printf( "Dowolny klawisz..." );
   
   
}

int main() {
    //Funkcja tworzy tablice kodow dla wszystkich znakow ASCII
    Inicjuj_tablice();
   
    Oblicz_CRC( "algorytmy i struktury danych" );
    getch();
    return 0;
}

Powiedziałby mi ktoś dlaczego nie działa ten kod ? Konkretne błędy :
" In function `void Oblicz_CRC(char*)':
61 invalid conversion from `unsigned char*' to `const char*'
61  initializing argument 1 of `size_t strlen(const char*)' "


P-162223
1551
Temat założony przez niniejszego użytkownika
» 2017-06-08 00:34:48
Potrzebuję jedynie pomocy w jaki sposób zamienić tę funkcję :
C/C++
void Oblicz_CRC( char * txt ) {
    //Wartosc poczatkowa to (2^32)-1
    unsigned long crc32 = 0xffffffff;
   
    int wynik;
    char kod[ 20 ];
   
    //Liczba bajtow do przetworzenia
    int dlugosc;
   
    //Tekst, dla ktorego obliczymy crc32
    char * tekst;
    //------------------------------------------------------------
   
    //Przykladowy tekst
    tekst =( char * ) txt;
    //dlugosc = strlen(tekst);
    dlugosc = strlen( txt );
    //Obliczaj crc przesuwajac kolejne znaki tekstu wejsciowego
    while( dlugosc-- )
         crc32 =( crc32 >> 8 ) ^ tablica[( crc32 & 255 ) ^* tekst++ ];
    //Wykonaj operacje XOR z wartoscia poczatkowa
    wynik = crc32 ^ 0xffffffff;
   
    //Zamien wynik na hex
    itoa( wynik, kod, 16 );
    printf( "Tekst wejsciowy: %s\n", txt );
    printf( "Suma CRC32: %s\n", kod );
    printf( "Dowolny klawisz..." );
   
   
}

na funkcję działającą na stringach, udało mi się zrobić coś takiego :
C/C++
void CRC( string txt ) {
    unsigned long crc32 = 0xffffffff;
   
    int result;
    char code[ 20 ];
   
    //Liczba bajtow do przetworzenia
    int length;
   
    //Tekst, dla ktorego obliczymy crc32
    string text;
    //------------------------------------------------------------
   
    //Przykladowy tekst
    text = txt;
    //dlugosc = strlen(tekst);
    length = txt.length();
    //Obliczaj crc przesuwajac kolejne znaki tekstu wejsciowego
    while( length-- )
         crc32 =( crc32 >> 8 ) ^ arr[( crc32 & 255 ) ^ text++ ]; //<----------------------------------------------------
    //Wykonaj operacje XOR z wartoscia poczatkowa
    result = crc32 ^ 0xffffffff;
   
    //Zamien wynik na hex
    itoa( result, code, 16 );
    cout << "Tekst wejsciowy: " << txt << endl;
    cout << "Suma CRC32: " << code << endl;
    cout << "Dowolny klawisz...";
   
   
}

Ale wyrzuca mi błąd w :
112 no `operator++(int)' declared for postfix `++', trying prefix operator instead
112  no match for 'operator++' in '++text'

Chodzi o linijkę zaznaczoną strzałką w kodzie.
P-162225
pekfos
» 2017-06-08 01:28:53
Jeśli nie masz nic przeciwko kopiowaniu kodu z dwóch źródeł naraz, to rozwiązanie już padło w tym temacie.
P-162229
1551
Temat założony przez niniejszego użytkownika
» 2017-06-08 01:32:11
Chodzi o rzutowanie?
P-162230
1 « 2 » 3 4
Poprzednia strona Strona 2 z 4 Następna strona