/*
Név: Kis Lázár Bence
Iskola: Magyar Tanítási Nyelvű Magángimnázium
Helység: Dunaszerdahely
Osztály: 11.

Fejlesztői környezet: Microsoft Visual Studio 2015
*/

#include <iostream>
#include <fstream>
#include <string>

using namespace std;


//-----------------------//
//   GLOBÁLIS VÁLTOZÓK   //
//-----------------------//

ifstream fIn;				// bemeneti fájl
ifstream fCode;				// kódot tartalmazó fájl
ofstream fOut;				// kimeneti fájl

char code[6][6];			// kódtábla
string keyWord;				// kódszó
string input;				// bemenet
string keyChars = "ADFGVX";	// sor- és oszlopazonosító karakterek
int order[10];				// karakterek abecedikus sorrendjét tároló tömb

//-----------------------//
//       FŐ PROGRAM      //
//-----------------------//

int main(int argc, char* argv[]) {
	string mode = argv[1];			// R vagy V
	string fCodeLoc = argv[2];		// kódot tartalmazó fájl helye
	string fInLoc = argv[3];		// bemeneti fájl helye
	string fOutLoc = argv[4];		// kimeneti fájl helye

	fIn.open(fInLoc, ios::in);
	fCode.open(fCodeLoc, ios::in);
	fOut.open(fOutLoc, ios::out);

	for (int i = 0; i < 6; i++) {		// kódtábla feltöltése
		string s;
		fCode >> s;
		for (int j = 0; j < 6; j++)
			code[i][j] = s[j];
	}
	fCode >> keyWord;		// kódszó beolvasása

	for (int i = 0; i < 10; i++)
		order[i] = i;

	for (int i = 0; i < keyWord.length(); i++)		// kódszó betűinek rendezése
		for (int j = 0; j < keyWord.length(); j++)
			if (keyWord[order[i]] < keyWord[order[j]])
				swap(order[i], order[j]);

	if (mode == "R") {		// rejtjelezés
		string s = "";
		fIn >> input;

		for (int k = 0; k < input.length(); k++) {
			bool ready = false;
			int i, j;
			for (i = 0; i < 6; i++) {		// karakter koordinátáinak megkeresése a kódtáblában
				for (j = 0; j < 6; j++) {
					if (code[i][j] == input[k]) {
						ready = true;
						break;
					}
				}
				if (ready)
					break;
			}
			s += keyChars[i];		// koordináták hozzáfűzése egy karakterlánchoz
			s += keyChars[j];
		}

		string encrypted = "";		// titkosított szöveg
		for (int i = 0; i < keyWord.length(); i++)
			for (int j = order[i]; j < s.length(); j += keyWord.length())	// j kezdeti értéke az első karaktertől való eltolódás
				encrypted += s[j];		// oszlopok összefűzése
		fOut << encrypted;
	}
	else if (mode == "V") {		// visszafejtés
		string encrypted;		// rejtjelezett szöveg
		fIn >> encrypted;

		string decrypted = "";	// visszafejtett szöveg
		string column[10];		// a kódszó egyes betűihez tartozó oszlopok
		for (int i = 0; i < keyWord.length(); i++) {
			int lettersInColumn = ceil((double)(encrypted.length() - i) / keyWord.length());	// betűk száma az adott oszlopban
			int offset = 0;		// azoknak a betűknek a száma, melyek a rejtjelezett szövegben a jelenlegi kódbetűhöz tartozó oszlop előtt találhatóak
			for (int j = 0; order[j] != i; j++)
					offset += ceil((double)(encrypted.length() - order[j]) / keyWord.length());
			for (int j = offset; j < lettersInColumn + offset; j++)
				column[i] += encrypted[j];		// jelenlegi betű oszlopának tárolása
		}
		for (int i = 0; i < encrypted.length(); i = i + 2) {
			int row, col;
			for (int j = 0; j < 6; j++)
				if (keyChars[j] == column[i % keyWord.length()][trunc(i / keyWord.length())])
					row = j;
			for (int j = 0; j < 6; j++)
				if (keyChars[j] == column[(i + 1) % keyWord.length()][trunc((i + 1) / keyWord.length())])
					col = j;
			decrypted += code[row][col];	// koordinátákhoz tartozó karakter hozzáfűzése a visszafejtett karakterlánchoz
		}
		fOut << decrypted;
	}

	return 0;
}