//******** created by mamo139 ********//
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
double * frequenze_load(double *,char *,long,long);
double * sort(double *,double *);
double * sort_indicizzato(double *frequenza,double *frequenza_in, char *indice);
int decifra(char * key, char * file, char * file2);
int main () {
long MAXchiave = 50; //lunghezza di chiave massima da cercare
long x=0,y=0,z=0,k=0;//dichiaro le variabili
double varianza=0,varianza_group=0;
double *frequenzebase,*frequenzebase_sort;
double *frequenzecript,*frequenzecript_sort;
double * frequenze;
double *varianze;
varianze = (double *) malloc((MAXchiave+1) * sizeof(double));
varianze[0]=0;
frequenzebase = (double *) malloc(256 * sizeof(double));
frequenzebase_sort = (double *) malloc(256 * sizeof(double));
frequenzecript = (double *) malloc(256 * sizeof(double));
frequenzecript_sort = (double *) malloc(256 * sizeof(double));
frequenze = (double *) malloc(256 * sizeof(double));
char *indicebase;
indicebase = (char *) malloc(256 * sizeof(char));
for(x=0;x<256;x++) indicebase[x]=x;
//prendo le frequenze del vocabolario
frequenzebase = frequenze_load(frequenzebase,"vocabolario.txt",0,1);
frequenzebase_sort = sort_indicizzato(frequenzebase_sort,frequenzebase,indicebase);
for(x=0;x<256;x++)
printf("%d:(%d) %c %f\n",x,(unsigned char)indicebase[x],indicebase[x],frequenzebase_sort[x]);
getchar();
for(x=1;x<=MAXchiave;x++){ //trovo le varianze di ogni lunghezza di chiave
printf("\nx = %d\n",x);
varianza_group=0;
for(y=0;y<x;y++){
frequenzecript = frequenze_load(frequenzecript,"cript.txt",y,x);
frequenzecript_sort = sort(frequenzecript_sort,frequenzecript);
varianza=0;
for(z=0;z<256;z++){
varianza = varianza + pow((frequenzebase_sort[z]-frequenzecript_sort[z]),2);
}
printf("varianza %f\n",varianza);
varianza_group=varianza_group+varianza;
}
varianze[x]=varianza_group/x;
printf("TOT%d: %f\n",x,varianze[x]);
}
long possibilechiave=1; //individuo la lunghezza della chiave
for(x=1;x<MAXchiave;x++)
if(varianze[x] < varianze[possibilechiave])
possibilechiave = x;
printf("\nla chiave probabilmente è lunga: %d\nvarianza: %f\n\n",possibilechiave,varianze[possibilechiave]);
//tentativo di crittanalisi mediante sostituzione secondo frequenze
FILE *in, *out;
long in_size,in_read;
in = fopen("cript.txt","rb");
fseek(in,0,SEEK_END);
in_size = ftell(in);
rewind(in);
out = fopen("output.txt","wb");
char *buffer;
buffer = (char *) malloc(in_size * sizeof(char));
char *buffer2;
buffer2 = (char *) malloc(in_size * sizeof(char));
in_read = fread(buffer,1,in_size,in);
char *indice;
indice = (char *) malloc(256 * sizeof(char));
for(x=0;x<possibilechiave;x++){
frequenzecript = frequenze_load(frequenzecript,"cript.txt",x,possibilechiave);
for(k=0;k<256;k++) indice[k]=k;
frequenzecript_sort = sort_indicizzato(frequenzecript_sort,frequenzecript,indice);
for(z=x;z<in_read;z=z+possibilechiave)
for(y=0;y<256;y++)
if(buffer[z]==indice[y]){
buffer2[z]=indicebase[y];
break;
}
}
fwrite(buffer2,1,in_read,out);
fclose(in);
fclose(out);
//possibile chiave mediante First Letter Attack (inventato da me)
char * FLAkey;
FLAkey = (char *) malloc(possibilechiave * sizeof(char));
for(y=0;y<possibilechiave;y++){
frequenzecript = frequenze_load(frequenzecript,"cript.txt",y,possibilechiave);
for(k=0;k<256;k++) indice[k]=k;
frequenzecript_sort = sort_indicizzato(frequenzecript_sort,frequenzecript,indice);
FLAkey[y] = abs(((unsigned char)indicebase[0])-((unsigned char)indice[0]));
}
FLAkey[possibilechiave] = '\0';
printf("Chiave secondo il First Letter Attack:\n%s\n",FLAkey);
decifra(FLAkey,"cript.txt","FLAoutput.txt");
getchar();
return 0;
}
double * frequenze_load(double *frequenze,char *filename,long partenza,long intervallo){
long lSize=0,b=0,x=0,somma=0,count=0;
FILE *stream;
stream = fopen(filename,"rb");
fseek (stream,0,SEEK_END);
lSize = ftell(stream);
rewind(stream);
unsigned char *buf;
buf = (unsigned char *) malloc(lSize * sizeof(unsigned char));
b=fread(buf,1,lSize,stream);
fclose (stream);
for(x=partenza;x<b;x=x+intervallo){
frequenze[buf[x]]++;
count++;
}
for(x=0;x<256;x++){
somma = somma+(long)frequenze[x];
}
for(x=0;x<256;x++){
frequenze[x]=frequenze[x]/count;
}
return frequenze;
}
double * sort(double *frequenza,double *frequenza_in){
long operations=1,x=0;
for(x=0;x<256;x++) frequenza[x]= frequenza_in[x];
double temp=0;
while(operations != 0){
operations = 0;
for(x=1;x<256;x++){
if(frequenza[x]>frequenza[(x-1)]){
temp=frequenza[x];
frequenza[x]=frequenza[(x-1)];
frequenza[(x-1)]=temp;
operations++;
}
}
}
return frequenza;
}
double * sort_indicizzato(double *frequenza,double *frequenza_in, char *indice){
long operations=1,x=0;
for(x=0;x<256;x++) frequenza[x]= frequenza_in[x];
double temp=0;
char temp2=0;
while(operations != 0){
operations = 0;
for(x=1;x<256;x++){
if(frequenza[x]>frequenza[(x-1)]){
temp=frequenza[x];
temp2=indice[x];
frequenza[x]=frequenza[(x-1)];
indice[x]=indice[(x-1)];
frequenza[(x-1)]=temp;
indice[(x-1)]=temp2;
operations++;
}
}
}
return frequenza;
}
//*** questa parte di codice è un po brutta ***//
int decifra(char * key, char * file, char * file2) {
FILE * pFile;
pFile = fopen ( file , "rb" );
long lSize,b,x,keyl=strlen(key);
printf("\n\nDECIFRAZIONE avviata con key: %s\n",key);
fseek (pFile , 0 , SEEK_END);
lSize = ftell (pFile);
fclose (pFile);
pFile = fopen ( file , "rb" );
char *buf;
buf = (char *) malloc(lSize * sizeof(char));
b=fread( buf, 1, lSize, pFile);
fclose (pFile);
FILE * f_out;
f_out = fopen ( file2 , "wb" );
for(x=0;x<b;x++){
buf[x] = ((unsigned char)buf[x]) - ((unsigned char)key[x%(keyl)]);
}
fwrite( buf, 1, b, f_out);
fclose (f_out);
return 0;
}