Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
JaVi - Java Vigenere - Vigenere.java

Vigenere.java

Caricato da: Teutoburgo
Scarica il programma completo

  1. /*
  2.   JaVi - JavaVigenere -   A Java implementation of the Vigenere
  3.                                 cryptographical  algorithm
  4.         Un'implementazione Java dell'algoritmo di
  5.                                 Vigenere per la crittografia
  6.     Copyright (C) 2002-2010 Pierre Blanc
  7.     Pierre Blanc: blanc_teutoburgo@yahoo.it
  8.     http://www.teutoburgo.tk                   (italiano)
  9.     http://teutoburgo.web44.net/indexEn.html   (english)
  10.  
  11.  
  12.     This program is free software; you can redistribute it and/or modify
  13.     it under the terms of the GNU General Public License as published by
  14.     the Free Software Foundation; either version 2 of the License.
  15.  
  16.     This program is distributed in the hope that it will be useful,
  17.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.     GNU General Public License for more details.
  20.  
  21.     You should have received a copy of the GNU General Public License
  22.     along with this program; if not, write to the Free Software
  23.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  24.     or go to      http://www.gnu.org/copyleft/gpl.html
  25.  
  26.  
  27.     Questo  programma è  software  libero; è  lecito redistribuirlo  o
  28.     modificarlo secondo i termini  della Licenza Pubblica Generica GNU
  29.     come è pubblicata dalla Free  Software Foundation, o la versione 2
  30.     della licenza.
  31.     Questo programma  è distribuito nella  speranza che sia  utile, ma
  32.     SENZA  ALCUNA GARANZIA;  senza  neppure la  garanzia implicita  di
  33.     NEGOZIABILITÀ  o di  APPLICABILITÀ PER  UN PARTICOLARE  SCOPO.  Si
  34.     veda la Licenza Pubblica Generica GNU per avere maggiori dettagli.
  35.  
  36.     Questo  programma deve  essere  distribuito assieme  ad una  copia
  37.     della Licenza Pubblica Generica GNU;  in caso contrario, se ne può
  38.     ottenere  una scrivendo  alla Free  Software Foundation,  Inc., 59
  39.     Temple Place, Suite 330, Boston, MA 02111-1307 USA  oppure da
  40.     http://www.gnu.org/copyleft/gpl.html
  41.  
  42.  
  43.     Un grazie sentito a Roberto detto "Piano Man" per l'importante aiuto.
  44.  
  45.  */
  46.  
  47. package JaVi;
  48.  
  49. import java.util.Vector;
  50. import java.util.Random;
  51.  
  52.  
  53. /**
  54.  *
  55.  * <p>Title: JaVi BO</p>
  56.  * <p>Description: La classe contenente l'algoritmo di Vigenere per cifrare e decifrare
  57.  * <br> The class containing the Vigenere algorithm to encrypt and decrypt</p>
  58.  * <p>Copyright: Copyright (c) 2002 Pierre Blanc</p>
  59.  * <p>Company: Teutoburgo</p>
  60.  * @author Pierre Blanc
  61.  * @version 1.02
  62.  */
  63.  
  64. public class Vigenere {
  65.  
  66. /*   int Unic0=32 (codice Unicode per ' '), UnicZ=122 (codice Unicode per 'Z');
  67.      I caratteri ammessi cadono nell'intervallo di codice Unicode 32-122.
  68.      Se si volesse modificare quest'intervallo bisognerebbe modificare il
  69.      sorgente.
  70.  
  71.      The accepted characters are within the Unicode set 32-122.
  72.      To modify this set you need to modify the source code.
  73. */
  74.  
  75.   int Unic0=32, UnicZ=123;
  76.   String mKey="MAX";
  77.  
  78.   public Vigenere() {
  79.   }
  80.  
  81.   public Vigenere(int u0, int uZ, String methodKey) {
  82.     Unic0=u0;
  83.     UnicZ=uZ;
  84.     mKey=methodKey;
  85.   }
  86. /**  Il metodo getEncryptedPhrase serve per cifrare la frase in chiaro
  87.     (String phrase) attraverso la chiave (String key).
  88. <br>
  89.     The method getEncryptedPhrase is to encrypt the phrase (String phrase)
  90.     using the key (String key).
  91.     @param phrase The phrase to be encrypted
  92.     @param key The key for the algorithm
  93.     @return The encrypted phrase
  94. */
  95.   public String getEncryptedPhrase (String phrase, String key){
  96.  
  97.     String tmp="", ad="";
  98.     String cryptedPhrase="";
  99.     char c,k;
  100.  
  101.     int lung1=phrase.length();
  102.     int lung2=key.length();
  103.     if (lung2==0) return ("Insert Key! - Inserire Chiave!");
  104.     if(lung1>lung2) {
  105.   tmp=key;
  106.   for (int i=0; i<lung1/lung2; i++){
  107.     tmp=tmp+key;
  108.   }
  109.   key=key+tmp;
  110.     }
  111.  
  112. /*   In questo ciclo viene applicato l'algoritmo: vengono sommati i codici
  113.      Unicode lettera per lettera della frase in chiaro e della chiave il
  114.      risultato modulo (UnicZ-Unic0) in modo che il risultato sia ancora un
  115.      codice Unicode compreso tra 32 e 122.
  116.  
  117.      In this cycle is applied the algorithm: the Unicode numbers of the phrase
  118.      and of the key are summed character per character and the result is
  119.      computed modulo (UnicZ-Unic0), so that the result is yet in
  120.      the Unicode set 32-122.
  121. */
  122.     for (int i=0; i<lung1; i++){
  123.       c=phrase.charAt(i);
  124.       k=key.charAt(i);
  125.       Character r=new Character((char)(((c+k)%(UnicZ-Unic0)+Unic0)));
  126.       cryptedPhrase=cryptedPhrase+r;
  127.     }
  128.  
  129.     return(cryptedPhrase);
  130.   }
  131.  
  132.  
  133. /**    Il metodo getPhrase serve per ottenere la frase in chiaro avendo la frase
  134.       cifrata (String cryptedPhrase) e la stessa chiave usata per cifrare
  135.       (String key)
  136. <br>
  137.   The method getPhrase is to get the phrase using the encrypted phrase
  138.   (String encryptedPhrase) and the same key used to encrypt (String key)
  139.  *
  140.  * @param cryptedPhrase the encrypted phrase
  141.  * @param key the key
  142.  * @return the plain text phrase
  143.  */
  144.  
  145.   public String getPhrase (String cryptedPhrase, String key){
  146.     int temp=0;
  147.     int mod=UnicZ-Unic0;
  148.     String ad="", tmp="";
  149.     String phrase="";
  150.     char r,k;
  151.  
  152.     int lung1=cryptedPhrase.length();
  153.     int lung2=key.length();
  154.     if (lung2==0) return ("Insert Key! - Inserire Chiave!");
  155.     if(lung1>lung2) {
  156.   tmp=key;
  157.   for (int i=0; i<lung1/lung2; i++){
  158.     tmp=tmp+key;
  159.   }
  160.   key=key+tmp;
  161.     }
  162. /*    In questo ciclo viene applicato l'algoritmo inverso: viene fatta la
  163.       differenza modulo (UnicZ-Unic0) dei codici Unicode.
  164.  
  165.       In this cycle is applied the inverse algorithm: it is done the difference
  166.       modulo (UnicZ-Unic0) between the Unicode numbers.
  167. */
  168.  
  169.     for (int i=0; i<lung1; i++){
  170.         r=cryptedPhrase.charAt(i);
  171.         k=key.charAt(i);
  172.         temp=((r-Unic0-k+4*mod)%(mod));
  173.         while (temp<Unic0) temp+=mod;
  174.         Character c=new Character((char)temp);
  175.         phrase=phrase+c;
  176.     }
  177.  
  178.     return(phrase);
  179.   }
  180.  
  181. /**
  182.  * Prende il double restituito da getKeyStrength e lo converte in un int
  183.    tra 0 e 100 per dare la percentuale di forza
  184. <br>
  185.    Converts the double returned by getKeyStrength into an int from 0 to 100
  186.    to give the strength in percent
  187.  * @param key the key
  188.  * @param accur the accuracy. The more is big, the more JaVi is slow.
  189.  * @return the key strength from 0 to 100.
  190.  */
  191.   public int getKSPerCent(String key, int accur){
  192.  
  193.     double kS=100-100*getKeyStrength(key, accur);
  194.     if (kS<0) kS=0;
  195.     return (int)kS;
  196.   }
  197.  
  198.  
  199. /**
  200.  * Restituisce un double tra 0 e 1 per valutare la forza della chiave.
  201.   Prende la chiave key, l'accuratezza accur (0 è il massimo della forza,
  202.   1 è la forza peggiore)
  203. <br>
  204.   Returns a double from 0 to 1 to evalue the strength of the key.
  205.   The parameters are the key key, the accuracy accur
  206.   (0 is the maximum strength, 1 is the minimum strength)
  207.  * @param key the key
  208.  * @param accur the accuracy
  209.  * @return a double from 0 to 1
  210.  */
  211.   public double getKeyStrength(String key, int accur){
  212.  
  213.     double [] devDepth=new double[accur];
  214.     double [] freqStringhe=new double[10000];
  215.     Vector freqStringheVect=new Vector();
  216.     int kMax=0, l=key.length();
  217.     int dim,j=0;
  218.     double dDtmp=0, dP;
  219.     double fMediaAtt=0;
  220.     double devMedia=0, devStand=0, devStandAtt=0;
  221.     int q=UnicZ-Unic0;
  222.  
  223.     if (l==0) return 1;
  224.     if (l-3<accur) accur=l-3;
  225.     if (accur<1) accur=1;
  226.  
  227.     for (int d=0; d<accur; d++){
  228.       freqStringheVect=trovaStringhe(key,d,q);
  229.       dim=freqStringheVect.size();
  230.       for (j=0; j<dim;j++){
  231.         freqStringhe[j]=((FrequenzaNijk)freqStringheVect.elementAt(j)).getFreq();
  232.       }
  233.       kMax=(int)Math.pow(q,d+1);
  234.       dP=(double)Math.min(kMax,l-d);
  235.       fMediaAtt=1/dP;
  236.  
  237.       for (j=0; j<dim; j++)
  238.         dDtmp=dDtmp+Math.pow((freqStringhe[j]-fMediaAtt),2);
  239.       devStand=Math.sqrt(dDtmp+(dP-dim)*Math.pow(fMediaAtt,2));
  240.     /*come misura della forza viene usata la deviazione standard della frequenze
  241.     dalla frequenza teorica attesa
  242.     in order to evalue the strength, the standard deviation of the frequencies
  243.     from the expected frequency is computed*/
  244.       devDepth[d]=devStand;
  245.       dDtmp=0;
  246.       /******* uncomment to view in the console the standard deviations
  247.       System.out.println("Depth: "+d+" Standard deviation: "+devStand);
  248.       */
  249.     }
  250.     if (mKey.equals("MAX"))
  251.       return maxKeyStrength(key, devDepth, accur);
  252.       else if (mKey.equals("AVE")) return averageKeyStrength(key, devDepth, accur);
  253.       else return defaultKeyStrength(key, devDepth, accur);
  254.   }
  255.  
  256.   /*i metodi defaultKeyStrength, minKeyStrength, averageKeyStrength
  257.   servono per staccare il calcolo della forza globale dal calcolo delle forze
  258.   considerando solo le stringhe di lunghezza j, che vengono passate nell'array
  259.   dD. Quello che cambia è il peso che viene dato alle forze di profondità j:
  260.   nel default il peso maggiore è dato alla forza di profondità j=1, per j=2 il
  261.   peso è la metà del peso per j=1, per j=3 la metà di j=2 e cosi' via
  262.  
  263.    the methods defaultKeyStrength, min.. , average.. are used to divide the
  264.    computing of the global strength from the computing of the strength obtained
  265.    by considering only the strings of length j, that are passed in the array
  266.    dD. It is different the weigth given to the strength of depth j: the
  267.    defaultKeyStrength gives the maximum weigth to the strength of depth j=1,
  268.    the half for j=2, and so on.. */
  269.  
  270.   public double defaultKeyStrength(String key, double [] dD, int dM){
  271.     double kS=0;
  272.     for (int j=0;j<dM;j++)
  273.       kS=kS+dD[j]/Math.pow(2,j+1);
  274.     return kS;
  275.   }
  276.  
  277. /**
  278.  * nel maxKeyStrength viene considerata unicamente la forza peggiore,
  279.   ovvero la massima (1 è la peggiore, 0 la migliore in assoluto)
  280. <br>
  281.   in maxKeyStrength it is considered only the worst strength, i.e. the
  282.   maximum (1 is the worst, 0 the best)
  283.  * @param key the key
  284.  * @param dD an array containing the strengths for the levels 1,2,...,dM
  285.  * @param dM the accuracy
  286.  * @return a double from 0 to 1
  287.  */
  288.   public double maxKeyStrength(String key, double [] dD, int dM){
  289.     double kS=0;
  290.     for (int j=0;j<dM;j++)
  291.       if (kS<dD[j]) kS=dD[j];
  292.     return kS;
  293.   }
  294.  
  295. /**
  296.  * nell'average viene restituita la forza media: è il metodo meno affidabile
  297.  
  298.   averageKeyStrength returns the average Strength: it's the less accurate
  299.   method
  300.  * @param key the key
  301.  * @param dD an array containing the strengths for the levels 1,2,...,dM
  302.  * @param dM the accuracy
  303.  * @return a double from 0 to 1
  304.  */
  305.   public double averageKeyStrength(String key, double [] dD, int dM){
  306.     double kS=0;
  307.     int l=key.length();
  308.     if (l<dM) dM=l;
  309.     for (int j=0;j<dM/3;j++)
  310.       kS=kS+dD[j];
  311.     kS=3*kS/dM;
  312.     return kS;
  313.   }
  314.  
  315.  
  316. /**
  317.  * il metodo restituisce un Vector di oggetti FrequenzaNijk
  318. <br>
  319.   returns a Vector of objects FrequenzaNijk
  320.  * @param key the key
  321.  * @param k the depth level (length of the String)
  322.  * @param q the symbols in the alphabet (UnicZ-Unic0)
  323.  * @return a Vector containing FrequenzaNijk objects
  324.  */
  325.   public Vector trovaStringhe(String key, int k, int q){
  326.     int kMax=(int)Math.pow(q,k+1);
  327.     int kMin=(int)Math.pow(q,k);
  328.     Vector vk= new Vector(0);
  329.     double v;
  330.     FrequenzaNijk fNijk=new FrequenzaNijk();
  331.     int l=key.length();
  332.     int r=l-k;
  333.     String trovata="";
  334.     int j,jMax=0;
  335.     Integer c;
  336.     double incr=1/((double)l-k);
  337.     boolean trovato=false;
  338.     FrequenzaNijk vt=new FrequenzaNijk();
  339.  
  340.     for (int i=0; i<r; i++){
  341.       trovato=false;
  342.       trovata=key.substring(i,i+k+1);
  343.       j=0;
  344.       while(!trovato && j<jMax){
  345.         vt=(FrequenzaNijk)vk.elementAt(j);
  346.         if(vt.getNijk().equals(trovata))
  347.           {
  348.            v=vt.getFreq();
  349.            vk.setElementAt(new FrequenzaNijk(trovata,v+incr),j);
  350.            trovato=true;
  351.           }
  352.         j++;
  353.       }
  354.       if (!trovato) {
  355.         vk.addElement(new FrequenzaNijk(trovata,incr));
  356.         jMax++;
  357.       }
  358.     }
  359.     int dim=vk.size();
  360.  
  361.     return vk;
  362.   }
  363.  
  364. /*    Questo main serve unicamente per testare i metodi di questa classe.
  365.  
  366.   This main method is presented only to test this class' methods.
  367. */
  368.  
  369.   public static void main(String[] args) {
  370.  //   System.out.println(-23%74);
  371.  
  372. //    System.out.println(Character.getNumericValue(' '));
  373.  
  374. /*    Vigenere vigenere1 = new Vigenere();
  375.   Random r=new Random();
  376. /* System.out.println(vigenere1.getKeyStrength("aaaaaa",5));
  377.  
  378.     for (int i=0; i<500; i++){
  379.       System.out.print((char)(32+r.nextInt(92)));
  380.     }*/
  381.  
  382.   /*  for (int i=0; i<91; i++){
  383.       System.out.print((char)(32+i%91));
  384.       System.out.print((char)(32+i%91));
  385.       System.out.print((char)(32+i%91));
  386.       System.out.print((char)(32+i%91));
  387.       System.out.print((char)(32+i%91));
  388.     }*/
  389. /*    for (int i=32; i<124; i++){
  390.     System.out.print((char)i);
  391.   }
  392.   for (int i=123; i>31; i--){
  393.     System.out.print((char)i);
  394.   }
  395.  
  396.  /*   System.out.println(vigenere1.getKeyStrength(
  397.     "ZoC%m]n.Y-q'gB'{@Xv/r;2%=kS.I.b@ka3mWG*utfq+{)no&F)[a;k,sWa6y.4eUh:xjV7SI#]/",12,92));
  398.     /*    char pi='C'+'0';
  399.     String chiave="ffffffffffffffffffffff";
  400. //    System.out.println(pi+" "+new Character((char)(((pi)%74)+48)));
  401.     String kr=vigenere1.getEncryptedPhrase("0Cicci333xyz",chiave);
  402.     System.out.println(kr);
  403.     System.out.println(vigenere1.getPhrase(kr,chiave));
  404. */
  405.   }
  406. }