2016-03-23 23 views
-2

Ben dizeler şifrelemek ve şifresini çözmek için bir program yazdım ve onunla küçük bir sorunu ...Java: Şifreleme Sayı

Kod yaşıyorum:

public static void main(String[] args) { 
     System.out.println("Welcome the small-scale RSA Testing Tool!"); 
     System.out.println("========================================= \n"); 
      System.out.println("Please type two relatively small prime numbers"); 
      Scanner ob=new Scanner(System.in); 
      System.out.print("p: "); 
      int p = ob.nextInt(); 

      System.out.print("\nq: "); 
      int q = ob.nextInt(); 

      System.out.println("\nn = p * q = " + p * q); 

      int t = (p-1) * (q-1); 
      System.out.println("t = (p-1) * (q-1) = " + t); 

      System.out.println("Please type an e that is relatively prime with t=" + t +" : "); 

      int e = ob.nextInt(); 

      int keys[] = rsaKeyGen(p, q, e); 

      System.out.println("Public Keys: n = " + keys[0] + " and e = " + keys[1] + "(published)"); 
      System.out.println("Private Key: d = " + keys[2] + " (You should keep this secret!)"); 

      System.out.println("Testing the encryption/decryption using the above generated keys: "); 

      else 
       System.out.print("Please type a text to encrypt (0 to exit): "); 
       String theString = ob.next(); //gets the string typed in 
       char[] ciphertext= new char[theString.length()]; 
       char[] normaltext= new char[theString.length()]; 
       char[] letters = new char[]{'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}; 
       BigDecimal y = null; 
       BigDecimal z = null; 
       for (int j=0; j<theString.length();j++) { //for each char in theString 
        char c = theString.charAt(j); 
        int index = c- 'a'; //subtracts value of a from c 
        y = rsaEncrypt(new BigDecimal(index), new BigDecimal(keys[1]), new BigDecimal(keys[0])); //encrypt 
        z = rsaDecrypt(y, new BigDecimal(keys[2]), new BigDecimal(keys[0])); //decrypt 
        ciphertext[j]=letters[y.intValue()%26];//mod 25 incase the value of y is bigger than letters in letters 
        normaltext[j]=letters[z.intValue()%26]; 
       } 
       String newString = new String(ciphertext); 
       System.out.println("Result: "+ theString +" encrypted to " + newString); // prints out encryption 
       System.out.println(""); 

       String decryptString = new String (normaltext); 

       System.out.println("Result: "+newString+" decrypted to " + decryptString); 

       if(decryptString.matches(theString)) System.out.println("It works!"); 
       else  System.out.println("It did not work, please check your implementation!"); 








     } 

    public static int[] egcd(int k, int j){ 
     List<Integer> quotients  = new ArrayList<Integer>(); 
     List<Integer> remainders = new ArrayList<Integer>(); 
     List<Integer> xs = new ArrayList<Integer>(); 
     List<Integer> ys = new ArrayList<Integer>(); 

     int oldK = k; 

     int quotient  = k/j; 
     int remainder = k % j; 
     int gcd = remainder==0?j:1; 
     while (remainder != 0){ 
      quotients.add(new Integer(quotient)); 
      remainders.add(new Integer(remainder)); 
      k = j; 
      j = remainder; 
      quotient  = k/j; 
      remainder = k % j; 
      gcd = j; 
     } 

     int result[] = new int[2]; 
     result[0] = gcd; 

     if(gcd != 1) { 
      System.out.println("These two numbers "+ j + " and " + k+ " are not relatively prime."); 
      System.exit(0); 

     } 
     xs.add(1); 
     ys.add(0); 

     int y = 1; 
     int x = 0 - ((int)quotients.remove(quotients.size()-1)) * 1; 
     int oldY = y; 
     int oldX = x; 

     while(quotients.size() > 0){ 
      y = x; 
      x = oldY - ((int)quotients.remove(quotients.size()-1)) * oldX; 
      oldY = y; 
      oldX = x; 
     } 


     result[1] = mod(new BigDecimal(x), new BigDecimal(oldK)).intValue(); 

     return result; 
    } 

    public static int[] rsaKeyGen(int p, int q, int e){ 
     int n, d, t; 
     int keys[] = new int[3]; 
     keys[0] = n = p * q; 
     keys[1] = e; 
     t = (p-1)*(q-1); 
     int gcdx[] = egcd(t, e); 
     keys[2] = gcdx[1]; 

     return keys; 
    } 

    public static BigDecimal rsaEncrypt(BigDecimal x, BigDecimal e, BigDecimal n){ 
     System.out.println("Encrypting " + x + " with e = " + e + " and n = " + n); 
     return mod(x.pow(e.intValue()), n); 
    } 

    public static BigDecimal rsaDecrypt(BigDecimal y, BigDecimal d, BigDecimal n){ 
     System.out.println("Decrypting " + y + " with d = " + d + " and n = " + n); 
     return mod(y.pow(d.intValue()), n); 
    } 

    public static BigDecimal mod(BigDecimal a, BigDecimal n){ 
     if(a.compareTo(new BigDecimal(0)) == -1) 
      return n.subtract(a.negate().remainder(n)); 
     else 
      return a.remainder(n); 
    } 
} 

Sonuç:

Result: abcdefghijklmnopzqrstuvzwxyz encrypted to ablmqrghistcdnopqefjkuaqblmq 

Result: ablmqrghistcdnopqefjkuaqblmq decrypted to abcdefghijklmnopeqrstuaebcde 
It did not work, please check your implementation! 

Farklı Gördüğünüz gibi, tüm harfler için çalışıyor ama v-z ve nerede yanlış gidiyorum emin değilim. Kodun bazılarını ekledim, ama belki de benden daha fazla bıraktım, çünkü hiç bir fikrim yok.

+0

Sorun, şifrenizde (başka sorunlara neden olabilir) değil, şifrelemede. Hem e hem de z, 'q' olarak şifrelenir, hem b hem de w, 'b' olarak şifrelenir ve 26 karakterinizden 9 karakter farklı bir karakter olarak şifrelenmez. –

cevap

0

Sorunumu çözdüm, 26'ya göre değiştirmek yerine, son birkaç harfi çalışmak için 27'ye geçmek zorunda kaldım.