#include <stdio.h>


// funkcia premiena znak 'A' az 'Z' alebo medzeru na cislo 0..26
int ctoi(char c)
{
	if (c >= 'A' && c <= 'Z') return c - 'A';
	if (c >= 'a' && c <= 'z') return c - 'a';
	return 26;
}


// funkcia premiena cislo 0..26 na znak 'A' az 'Z' alebo medzeru
char itoc(int i)
{
	if (i >= 0 && i <= 25) return i + 'A';
	return ' ';
}


// funkcia a + b mod 27
int add(int a, int b)
{
	return (a + b) % 27;
}


// funkcia a * b mod 27
int mul(int a, int b)
{
	return (a * b) % 27;
}


// funkcia a^-1 mod 27
int inv(int a)
{
	int b;
	for (b = 1; b < 27; b++) {
		if (mul(a,b) == 1) return b;
	}
	return 0;
}


// vstupny retazec
const char *input = "AHOJ";


// vystupny buffer
char output[1000];
char output2[1000];

int main(int argc, char *argv[])
{
	// sifrovacie kluce k1 a k2
	int k1 = 2, k2 = 5;
	int k1c, k2c;
	

	// ciselny kod priameho a zasifrovaneho pismena
	int p, c;

	// ukazovatele pozicie priameho a zasifrovaneho buffera
	const char *src = input;
	char *dest = output;
	
	// sifrovanie
	while (*src != '\0') {
		p = ctoi(*src);
		c = add(mul(k1,p), k2); // c = k1 * p + k2 mod 27
		*dest = itoc(c);
		src++; dest++;
	}
	*dest = '\0';

	printf("Priamy text: %s\nZasifrovany text: %s\n", input, output);
	

	// vypocet desifrovacich klucov
	k1c = inv(k1);
	k2c = mul(k1c, 27-k2);

	src = output;
	dest = output2;
	
	// desifrovanie
	while (*src != '\0') {
		c = ctoi(*src);
		p = add(mul(k1c,c), k2c); // p = k1' * c + k2' mod 27
		*dest = itoc(p);
		src++; dest++;
	}
	*dest = '\0';

	printf("Priamy text: %s\n", output2);
	
	return 0;
}
