// CRC-8/MAXIM string calulator
// Date 01:25 15/12/2016
// By Ben a.k.a DreamVB

#include <string>
#include <iostream>
#include <sstream>
#include <stdint.h>

using namespace std;
using std::cout;
using std::endl;

uint16_t  CalcCRC16(char *src){
	int aByte = 0;
	uint16_t crc = 0;
	uint16_t sum = 0;
	const int bMask = 0x01;

	crc = 0;

	for (int i = 0; i < strlen(src); i++){
		//Get byte
		aByte = (int)src[i];

		for (int j = 0; j < 8;j++){
			//Calculate crc
			sum = (crc ^ aByte) & bMask;
			crc = (crc >> bMask);

			if (sum == 1){
				crc = (crc ^ 0x8C);
			}
			aByte = (aByte >> bMask);
		}
	}
	//Return crc value.
	return crc;
}

string IntToHex(unsigned short value){
	ostringstream os;
	//Convert int to hex and uppercase
	os << std::hex << std::uppercase << value;
	//Return hex string
	return os.str();
}

int main(int argc, char *argv[]){
	char buff[80];
	char c = 'Y';
	uint16_t crc_val = 0;

	while (c != 'N'){
		system("cls");
		cout << "--- CRC-8/MAXIM string calulator ---\n";
		cout << "\nEnter a string to calulate CRC : ";
		//Get inout line.
		gets(buff);
		//Get crc value
		crc_val = CalcCRC16(buff);
		//Show results.
		cout << "\nCRC Details\n";
		cout << "Decimmal    : " << crc_val << endl;
		cout << "Hexidecimal : 0x" << IntToHex(crc_val) << endl;
		
		//Ask if the user wants to run the program agian.
		cout << "\nDo you want calulate a new crc value : (Y/N) : ";
		cin >> c;
		c = toupper(c);

		if (c == 'N'){
			cout << "\tThanks for trying the program.\n";
			break;
		}
		if (c != 'Y'){
			cout << "Invaild choice program will now exit.\n";
			break;
		}

		cin.ignore();
		cin.clear();
	}

	system("pause");
	return EXIT_SUCCESS;
}