Italiano
HOME | PROGETTI | CLASSI C++ | Sorgenti c\c++ | Galleria | Guestbook | Server BW | Contattami | Login

<< Crittoanalisi Vigenerč >>

visiste: 4198


Questo codice mi ha dato una particolare soddisfazione. Il programma sfrutta l'analisi delle frequenze per provare a decifrare un file di TESTO crittograto con il cifrario di Vigenerč.
Per capire a fondo il metodo utilizzato č bene conoscere il concetto di varianza.

Il programma ha una decifrazione quasi sempre perfetta quando il rapporto testo /chiave č uguale o maggiore a 100 (ad esempio un file di 5kb č facilmente leggibile se la chiave č uguale o minore a 50byte).

Le funzioni piu interessanti:
1)comunica la lunghezza della chiave
2)crea il file output.txt in cui prova a decrittografare solo utilizzando le frequenze
3)bisogna inserire del testo nella lingua che si vuole decifrare nel file vocabolario.txt
4)crea l'output della decifrazione secondo l'attacco della prima lettera *.

* L'attacco della prima lettera si basa sul concetto che lo spazio č praticamente sempre il carattere piu ripetuto e quindi quando si confrontano i cifrari c'č una buona possibilitą che il primo carattere di ogni cifrario sia uno spazio.

  1. //******** created by mamo139 ********//
  2.  
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. #include <math.h>
  7.  
  8. double * frequenze_load(double *,char *,long,long);
  9. double * sort(double *,double *);
  10. double * sort_indicizzato(double *frequenza,double *frequenza_in, char *indice);
  11.  
  12. int decifra(char * key, char * file, char * file2);
  13.  
  14. int main () {
  15. long MAXchiave = 50; //lunghezza di chiave massima da cercare
  16.  
  17. long x=0,y=0,z=0,k=0;//dichiaro le variabili
  18. double varianza=0,varianza_group=0;
  19. double *frequenzebase,*frequenzebase_sort;
  20. double *frequenzecript,*frequenzecript_sort;
  21. double * frequenze;
  22. double *varianze;
  23. varianze = (double *) malloc((MAXchiave+1) * sizeof(double));
  24. varianze[0]=0;
  25. frequenzebase = (double *) malloc(256 * sizeof(double));
  26. frequenzebase_sort = (double *) malloc(256 * sizeof(double));
  27. frequenzecript = (double *) malloc(256 * sizeof(double));
  28. frequenzecript_sort = (double *) malloc(256 * sizeof(double));
  29. frequenze = (double *) malloc(256 * sizeof(double));
  30. char *indicebase;
  31. indicebase = (char *) malloc(256 * sizeof(char));
  32. for(x=0;x<256;x++) indicebase[x]=x;
  33.  
  34. //prendo le frequenze del vocabolario
  35. frequenzebase = frequenze_load(frequenzebase,"vocabolario.txt",0,1);
  36. frequenzebase_sort = sort_indicizzato(frequenzebase_sort,frequenzebase,indicebase);
  37.  
  38. for(x=0;x<256;x++)
  39. printf("%d:(%d) %c %f\n",x,(unsigned char)indicebase[x],indicebase[x],frequenzebase_sort[x]);
  40.  
  41. getchar();
  42.  
  43. for(x=1;x<=MAXchiave;x++){ //trovo le varianze di ogni lunghezza di chiave
  44. printf("\nx = %d\n",x);
  45. varianza_group=0;
  46. for(y=0;y<x;y++){
  47. frequenzecript = frequenze_load(frequenzecript,"cript.txt",y,x);
  48. frequenzecript_sort = sort(frequenzecript_sort,frequenzecript);
  49. varianza=0;
  50. for(z=0;z<256;z++){
  51. varianza = varianza + pow((frequenzebase_sort[z]-frequenzecript_sort[z]),2);
  52. }
  53. printf("varianza %f\n",varianza);
  54. varianza_group=varianza_group+varianza;
  55. }
  56. varianze[x]=varianza_group/x;
  57. printf("TOT%d: %f\n",x,varianze[x]);
  58. }
  59.  
  60. long possibilechiave=1; //individuo la lunghezza della chiave
  61. for(x=1;x<MAXchiave;x++)
  62. if(varianze[x] < varianze[possibilechiave])
  63. possibilechiave = x;
  64. printf("\nla chiave probabilmente č lunga: %d\nvarianza: %f\n\n",possibilechiave,varianze[possibilechiave]);
  65.  
  66. //tentativo di crittanalisi mediante sostituzione secondo frequenze
  67. FILE *in, *out;
  68. long in_size,in_read;
  69. in = fopen("cript.txt","rb");
  70. fseek(in,0,SEEK_END);
  71. in_size = ftell(in);
  72. rewind(in);
  73. out = fopen("output.txt","wb");
  74. char *buffer;
  75. buffer = (char *) malloc(in_size * sizeof(char));
  76. char *buffer2;
  77. buffer2 = (char *) malloc(in_size * sizeof(char));
  78. in_read = fread(buffer,1,in_size,in);
  79. char *indice;
  80. indice = (char *) malloc(256 * sizeof(char));
  81. for(x=0;x<possibilechiave;x++){
  82. frequenzecript = frequenze_load(frequenzecript,"cript.txt",x,possibilechiave);
  83. for(k=0;k<256;k++) indice[k]=k;
  84. frequenzecript_sort = sort_indicizzato(frequenzecript_sort,frequenzecript,indice);
  85. for(z=x;z<in_read;z=z+possibilechiave)
  86. for(y=0;y<256;y++)
  87. if(buffer[z]==indice[y]){
  88. buffer2[z]=indicebase[y];
  89. break;
  90. }
  91. }
  92. fwrite(buffer2,1,in_read,out);
  93. fclose(in);
  94. fclose(out);
  95.  
  96. //possibile chiave mediante First Letter Attack (inventato da me)
  97. char * FLAkey;
  98. FLAkey = (char *) malloc(possibilechiave * sizeof(char));
  99.  
  100. for(y=0;y<possibilechiave;y++){
  101. frequenzecript = frequenze_load(frequenzecript,"cript.txt",y,possibilechiave);
  102. for(k=0;k<256;k++) indice[k]=k;
  103. frequenzecript_sort = sort_indicizzato(frequenzecript_sort,frequenzecript,indice);
  104. FLAkey[y] = abs(((unsigned char)indicebase[0])-((unsigned char)indice[0]));
  105. }
  106. FLAkey[possibilechiave] = '\0';
  107.  
  108. printf("Chiave secondo il First Letter Attack:\n%s\n",FLAkey);
  109.  
  110. decifra(FLAkey,"cript.txt","FLAoutput.txt");
  111.  
  112. getchar();
  113. return 0;
  114. }
  115.  
  116. double * frequenze_load(double *frequenze,char *filename,long partenza,long intervallo){
  117.  
  118. long lSize=0,b=0,x=0,somma=0,count=0;
  119.  
  120. FILE *stream;
  121. stream = fopen(filename,"rb");
  122. fseek (stream,0,SEEK_END);
  123. lSize = ftell(stream);
  124. rewind(stream);
  125.  
  126. unsigned char *buf;
  127. buf = (unsigned char *) malloc(lSize * sizeof(unsigned char));
  128.  
  129. b=fread(buf,1,lSize,stream);
  130. fclose (stream);
  131.  
  132. for(x=partenza;x<b;x=x+intervallo){
  133. frequenze[buf[x]]++;
  134. count++;
  135. }
  136.  
  137. for(x=0;x<256;x++){
  138. somma = somma+(long)frequenze[x];
  139. }
  140.  
  141. for(x=0;x<256;x++){
  142. frequenze[x]=frequenze[x]/count;
  143. }
  144.  
  145. return frequenze;
  146. }
  147.  
  148. double * sort(double *frequenza,double *frequenza_in){
  149. long operations=1,x=0;
  150. for(x=0;x<256;x++) frequenza[x]= frequenza_in[x];
  151. double temp=0;
  152. while(operations != 0){
  153. operations = 0;
  154. for(x=1;x<256;x++){
  155. if(frequenza[x]>frequenza[(x-1)]){
  156. temp=frequenza[x];
  157. frequenza[x]=frequenza[(x-1)];
  158. frequenza[(x-1)]=temp;
  159. operations++;
  160. }
  161. }
  162. }
  163. return frequenza;
  164. }
  165.  
  166. double * sort_indicizzato(double *frequenza,double *frequenza_in, char *indice){
  167. long operations=1,x=0;
  168. for(x=0;x<256;x++) frequenza[x]= frequenza_in[x];
  169. double temp=0;
  170. char temp2=0;
  171. while(operations != 0){
  172. operations = 0;
  173. for(x=1;x<256;x++){
  174. if(frequenza[x]>frequenza[(x-1)]){
  175. temp=frequenza[x];
  176. temp2=indice[x];
  177. frequenza[x]=frequenza[(x-1)];
  178. indice[x]=indice[(x-1)];
  179. frequenza[(x-1)]=temp;
  180. indice[(x-1)]=temp2;
  181. operations++;
  182. }
  183. }
  184. }
  185. return frequenza;
  186. }
  187.  
  188. //*** questa parte di codice č un po brutta ***//
  189. int decifra(char * key, char * file, char * file2) {
  190. FILE * pFile;
  191. pFile = fopen ( file , "rb" );
  192. long lSize,b,x,keyl=strlen(key);
  193. printf("\n\nDECIFRAZIONE avviata con key: %s\n",key);
  194. fseek (pFile , 0 , SEEK_END);
  195. lSize = ftell (pFile);
  196. fclose (pFile);
  197. pFile = fopen ( file , "rb" );
  198. char *buf;
  199. buf = (char *) malloc(lSize * sizeof(char));
  200. b=fread( buf, 1, lSize, pFile);
  201. fclose (pFile);
  202. FILE * f_out;
  203. f_out = fopen ( file2 , "wb" );
  204. for(x=0;x<b;x++){
  205. buf[x] = ((unsigned char)buf[x]) - ((unsigned char)key[x%(keyl)]);
  206. }
  207. fwrite( buf, 1, b, f_out);
  208. fclose (f_out);
  209. return 0;
  210. }
  211.  
Versione sito: 1.03.01 by mamo139. - Tutti i sorgenti presenti su questo sito sono rilasciati sotto licenza "GNU GPL version 3".