Last active
March 5, 2018 19:04
-
-
Save RicardoLara/0ec2242084df4c13d34965b306a09d5a to your computer and use it in GitHub Desktop.
HillCipherv2 - Archivos y División.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <bits/stdc++.h> | |
using namespace std; | |
char Alfabeto[62]; | |
int sizeK = 3, numLetras = 62; | |
int k[3][3]; | |
int kEstrella[3][3]; | |
string salida,cad; | |
int Algo1(int a, int b){ | |
int u = a; int v = b; | |
int x1 = 1; int y1 = 0; int x2 = 0; int y2 = 1; | |
int q,r,x,y,d; | |
while(u != 0){ | |
q = (v/u); r = v - q*u; x = x2 - q*x1; y = y2 - q*y1; | |
v = u; u = r; x2 = x1; x1 = x; y2 = y1; y1 = y; | |
} | |
d = v; x = x1; y = y2; | |
cout << d << " " << x << " " << y << endl; | |
} | |
int Algo2(int a, int p){ | |
int u = a; int v = p; | |
int x1 = 1; int x2 = 0; | |
int q,r,x,y,d; | |
while(u != 1){ | |
q = (v/u); r = v - q*u; x = x2 - q*x1; | |
v = u; u = r; x2 = x1; x1 = x; | |
} | |
return x1; | |
//cout << x1 << " mod " << p << endl; | |
} | |
int det(int a1, int a2, int b1, int b2){ | |
return a1*b2 - a2*b1; | |
} | |
int indexAlfabeto(char x){ | |
for(int i=0; i<62; i++) | |
if(Alfabeto[i] == x) | |
return i; | |
return -1; | |
} | |
void llenarAlfabeto(){ | |
int i; | |
for(i=65; i<91; i++) Alfabeto[i-65] = i; | |
for(i=97; i<123; i++) Alfabeto[i-71] = i; | |
for(i=48; i<58; i++) Alfabeto[i+4] = i; | |
} | |
int cifrarHill(string NamePlaintext, string NameCiphertext, string NameKey){ | |
ifstream inFile; int valor; | |
inFile.open(NameKey.c_str(), ios::in); | |
if (!inFile){ | |
cout << "\nError opening file.\n"; | |
return 0; | |
} | |
for(int j=0; j<3; j++) | |
for(int y=0; y<3; y++) | |
inFile >> k[j][y]; | |
inFile.close(); | |
string linea; salida = ""; cad = ""; | |
inFile.open(NamePlaintext.c_str(), ios::in); | |
if(!inFile){ | |
cout << "\nError opening file.\n"; | |
return 0; | |
} | |
while(getline(inFile,linea)) | |
cad += linea; | |
cout << "Texto original => \t" << cad << endl; | |
for(int i=0; i<cad.length(); i+=sizeK){ | |
int x,y,z; | |
x = indexAlfabeto(cad[i]); | |
y = indexAlfabeto(cad[i+1]); | |
z = indexAlfabeto(cad[i+2]); | |
for (int j = 0; j < sizeK; j++){ | |
int caracter = (x*k[j][0] + y*k[j][1] + z*k[j][2]) % numLetras; | |
salida += Alfabeto[caracter]; | |
} | |
} | |
salida += '\0'; | |
ofstream archivoSalida(NameCiphertext.c_str()); | |
archivoSalida << salida; | |
archivoSalida.close(); | |
cout << "Cifrado queda => \t" << salida << endl; | |
return 1; | |
} | |
void descifrarHill(string NameCiphertext, string NewPlaintext, string NameKey){ | |
string aux = ""; | |
int sizeK = 3; | |
int detK = k[0][0]*det(k[1][1],k[1][2],k[2][1],k[2][2]) - | |
k[0][1]*det(k[1][0],k[1][2],k[2][0],k[2][2]) + | |
k[0][2]*det(k[1][0],k[1][1],k[2][0],k[2][1]); | |
detK %= numLetras; | |
int invDetK = Algo2(detK,numLetras); if(invDetK<0) invDetK += numLetras; | |
//Matriz Transpuesta | |
int C[3][3]; | |
C[0][0] = det(k[1][1],k[1][2],k[2][1],k[2][2]); //C11 | |
C[0][1] = -1*det(k[1][0],k[1][2],k[2][0],k[2][2]); //C12 | |
C[0][2] = det(k[1][0],k[1][1],k[2][0],k[2][1]); //C13 | |
C[1][0] = -1*det(k[0][1],k[0][2],k[2][1],k[2][2]); //C21 | |
C[1][1] = det(k[0][0],k[0][2],k[2][0],k[2][2]); //C22 | |
C[1][2] = -1*det(k[0][0],k[0][1],k[2][0],k[2][1]); //C23 | |
C[2][0] = det(k[0][1],k[0][2],k[1][1],k[1][2]); //C31 | |
C[2][1] = -1*det(k[0][0],k[0][2],k[1][0],k[1][2]); //C32 | |
C[2][2] = det(k[0][0],k[0][1],k[1][0],k[1][1]); //C33 | |
//K-1 | |
kEstrella[0][0] = (C[0][0]*invDetK) % numLetras; if(kEstrella[0][0] < 0) kEstrella[0][0]+=numLetras; | |
kEstrella[0][1] = (C[1][0]*invDetK) % numLetras; if(kEstrella[0][1] < 0) kEstrella[0][1]+=numLetras; | |
kEstrella[0][2] = (C[2][0]*invDetK) % numLetras; if(kEstrella[0][2] < 0) kEstrella[0][2]+=numLetras; | |
kEstrella[1][0] = (C[0][1]*invDetK) % numLetras; if(kEstrella[1][0] < 0) kEstrella[1][0]+=numLetras; | |
kEstrella[1][1] = (C[1][1]*invDetK) % numLetras; if(kEstrella[1][1] < 0) kEstrella[1][1]+=numLetras; | |
kEstrella[1][2] = (C[2][1]*invDetK) % numLetras; if(kEstrella[1][2] < 0) kEstrella[1][2]+=numLetras; | |
kEstrella[2][0] = (C[0][2]*invDetK) % numLetras; if(kEstrella[2][0] < 0) kEstrella[2][0]+=numLetras; | |
kEstrella[2][1] = (C[1][2]*invDetK) % numLetras; if(kEstrella[2][1] < 0) kEstrella[2][1]+=numLetras; | |
kEstrella[2][2] = (C[2][2]*invDetK) % numLetras; if(kEstrella[2][2] < 0) kEstrella[2][2]+=numLetras; | |
for(int i=0; i<cad.length(); i+=sizeK){ | |
int x,y,z; | |
x = indexAlfabeto(salida[i]); //printf("salida[%d] => [%d](%c)\n",i,x,Alfabeto[x]); | |
y = indexAlfabeto(salida[i+1]); //printf("salida[%d] => [%d](%c)\n",i+1,y,Alfabeto[y]); | |
z = indexAlfabeto(salida[i+2]); //printf("salida[%d] => [%d](%c)\n",i+2,y,Alfabeto[z]); | |
for (int j = 0; j < sizeK; j++){ | |
int caracter = (x*kEstrella[j][0] + y*kEstrella[j][1] + z*kEstrella[j][2]) % numLetras; | |
aux += Alfabeto[caracter]; | |
} | |
} | |
aux += '\0'; | |
ofstream archivoSalida2(NewPlaintext.c_str()); | |
archivoSalida2 << aux; | |
archivoSalida2.close(); | |
cout << "Descifrado queda => \t" << aux << endl; | |
} | |
int main(){ | |
llenarAlfabeto(); | |
string nombrePlain,nombreCipher,nombreKey,nombreSalida; | |
cout << "Nombre del archivo con el texto plano (Incluyendo extension): "; | |
cin >> nombrePlain; | |
cout << "Nombre del archivo con el texto cifrado (Incluyendo extension): "; | |
cin >> nombreCipher; | |
cout << "Nombre del archivo con la clave K (Incluyendo extension): "; | |
cin >> nombreKey; | |
cout << "Nombre del archivo con el texto DEScifrado (Incluyendo extension): "; | |
cin >> nombreSalida; | |
int len = cifrarHill(nombrePlain,nombreCipher,nombreKey); | |
if( len == 0) return 0; | |
descifrarHill(nombreCipher,nombreSalida,nombreKey); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment