Skip to content

Instantly share code, notes, and snippets.

@RicardoLara
Last active March 5, 2018 19:04
Show Gist options
  • Save RicardoLara/0ec2242084df4c13d34965b306a09d5a to your computer and use it in GitHub Desktop.
Save RicardoLara/0ec2242084df4c13d34965b306a09d5a to your computer and use it in GitHub Desktop.
HillCipherv2 - Archivos y División.
#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