/* Doppia cifratura (IOI 2001) Copyright (C) 2001 Alessandro Maconi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA (Come per tutti i problemi del 2001, è utile leggere il libretto distribuito dagli organizzatori, e disponibile nella sezione "Materiale didattico" della home page http://ioi.dsi.unimi.it/.) Questa soluzione calcola prima tutti i testi in cifra possibili con la prima chiave, li ordina, e quindi tenta tutti i testi in cifra possibili con la seconda chiave, cercando ciascuno di essi tramite ricerca binaria nel primo insieme. */ #include #include #include #include #include "aeslibc.h" /* per utilizzare le funzioni fornite per cifrare e decifrare */ #define LNG 20 /* lunghezza max nome del file (potrebbe essere 13, ma meglio abbondare) */ #define NF 10 typedef struct { HexStr ris; char key[6]; }str; int nbit; /* num di cifre su cui lavorare */ HexStr chiaro,cifrata,tmp,key; /* le due stringhe su cui lavorare */ Block bch,bcr,btmp,bkey; /* x lavorare bisogna utilizzare le chiavi codificate */ char chiave[6]; void conv(int x); /* converte il numero passato come argomento nella chiave da utilizzare */ int comp(const void *a,const void *b); int main() { int i,j; FILE *fin,*fout; char nomef[LNG]; /* per tenere il nome del file su cui si sta lavorando */ str *array; /* array in cui teniamo i risultati */ str *a; int lungh; /* dimensione dell'array */ for(i=0;i<=NF;i++) /* lavoriamo su 10 file con nomi da 1 a 10 */ { sprintf(nomef,"double%d.in",i); fin=fopen(nomef,"r"); fscanf(fin,"%d",&nbit); fscanf(fin,"%s",chiaro); fscanf(fin,"%s",cifrata); hexstr2block(chiaro,bch); hexstr2block(cifrata,bcr); lungh=(long)powl(16,nbit); array=(str*)calloc(lungh,sizeof(str)); for(j=0;jkey); fprintf(fout,"%s\n",key); fclose(fin); fclose(fout); free(array); } return 0; } void conv(int x) { int i,n; for(i=0;i<5;i++) { n=x%16; x/=16; switch(n) { case 0: chiave[i]='0'; break; case 1: chiave[i]='1'; break; case 2: chiave[i]='2'; break; case 3: chiave[i]='3'; break; case 4: chiave[i]='4'; break; case 5: chiave[i]='5'; break; case 6: chiave[i]='6'; break; case 7: chiave[i]='7'; break; case 8: chiave[i]='8'; break; case 9: chiave[i]='9'; break; case 10: chiave[i]='A'; break; case 11: chiave[i]='B'; break; case 12: chiave[i]='C'; break; case 13: chiave[i]='D'; break; case 14: chiave[i]='E'; break; case 15: chiave[i]='F'; break; } } chiave[i]='\0'; sprintf(key,"%s000000000000000000000000000",chiave); } int comp(const void *a,const void *b) { str *c,*d; c=(str*)a; d=(str*)b; return strcmp(c->ris,d->ris); }