// Jakub Mackowiak T-TIZ
// mackowiak.jakub@gmail.com
//
// Biblioteka Boost::CRC
//

#include "stdafx.h"
#include <boost/crc.hpp>	// biblioteka CRC

#include <iostream>			// Obsluga strumieniu wyjscia
#include <ctime>			// Ziarno dla generatora liczb losowych
#include <bitset>			// Do przeksztalcenia wyjsciowego kodu na postac binarna


int _tmain(int argc, _TCHAR* argv[])
{
	// Wylosowanie danych liczbowych ktore posluza za wiadomosc
	srand((unsigned)time(0));
	int data[] = {rand(), rand(), rand(), rand()};
	std::size_t const    data_len = sizeof( data )/ sizeof( data[0] );

	//Stworzenie obiektu klasy Podstawowej z zadanymi parametrami
	//Parametr szablonu - Rozmiar
	//Parametry konstruktora - Truncated polynominal, Initial remainder, Final XOR value, Reflected input, Reflected output
	boost::crc_basic<16>  crc_podst( 0x8005, 0x0, 0, false, false );
    

	//Stworzenie obiektu klasy Optymalnej z zadanymi parametrami
	boost::crc_optimal<16, 0x8005, 0x0, 0, false, false>  crc_opt;
	
	//Obliczenie kodu nadmiarowego przez obie klasy
	crc_podst.process_bytes( data, data_len );
	crc_opt.process_bytes( data, data_len );

	//Wypisanie danych wejsciowych (wiadomosci) i wynikowych ciagow kodowych
	std::cout << std::endl << "Dane: " <<data[0] << ", " << data[1] << ", " << data[2] << ", " << data[3];
	std::cout << std::endl << "CRC basic: " << std::bitset<16>(crc_podst.checksum()) << ", CRC optimal: " << std::bitset<16>(crc_opt.checksum());

	//Reset obiektow (majacy na celu ustawienie Remainder na 0)
	crc_podst.reset();
	crc_opt.reset();

	//Podmiana pojedynczego bitu w wybranej 'losowo' liczbie z tablicy danych 
	// data[ data[0] % data_len ] -> 'losowe' wybranie ktora z liczb ulegnie zmianie
	// ^= operator bitowy przyipsania
	// ( 1 << (data[1] % 32) ) -> wpisz 1 w 'losowe' miejsce znaczace ciagu wybranego int'a
	data[ data[0] % data_len ] ^= ( 1 << (data[1] % 32) );

	//Ponowne obliczenie kodow nadmiarowych
	crc_podst.process_bytes( data, data_len );
	crc_opt.process_bytes( data, data_len );

	//Wyswietlenie zmienionych danych i odpowiadajacych im kodow
	std::cout << std::endl << "Podmiana jednego bitu."<< std::endl <<"Dane: " <<data[0] << ", " << data[1] << ", " << data[2] << ", " << data[3];
	std::cout << std::endl << "CRC basic: " << std::bitset<16>(crc_podst.checksum()) << ", CRC optimal: " << std::bitset<16>(crc_opt.checksum());
	//Wniosek: Zastosowana dlugosc kodu nadmiarowego (16 bitow), dla tak dlugiej wiadomosci (32*4=128 bitow)
	//czesto nie wykrywa zmiany pojedynczego bitu. Rozwiazanie - stosowac dluzszy kod nadmiarowy/dzielic wiadomosc na mniejsze
	//Ewentualne zastosowanie podobnego programu - statystyka skutecznosci detekcji kodow nadmiarowych dla zadanych: dlugosci 
	//kodu nadmiarowego, dlugosci wiadomosci, zastosowanego wielomianu dzielacego.
	
	return 0;
}

