2014-10-12 61 views
0

你好evrybody誰讀這個!Vigenere密碼java UTF-8

我需要在Java上實現Vigenere密碼。 我有一個.txt文檔,我將閱讀,編碼和解碼。那就是:

ASCII  abcde xyz 
German äöü ÄÖÜ ß 
Polish ąęźżńł 
Russian абвгдеж эюя 
CJK  你好 

我的問題是,我不知道如何正確地轉移字符,根據this table拉丁字母有從0061到007A碼。我需要的德國人:00C0 - 00FF,波蘭人:0100-017F,俄羅斯人0430-044F,我沒有吃過中國菜。

我該如何指定unshiftCharshiftChar才能使它更加活躍? 現在我的輸入是這樣的:

The original text from file is: 
ASCII  abcde xyz 
German äöü ÄÖÜ ß 
Polish ąęźżńł 
Russian абвгдеж эюя 
CJK  你好 

String that will be encoded is: 
asciiabcdexyzgermanäöüäöüßpolishąęźżńłrussianабвгдежэюяcjk你好 

The encrypted string is: 
äckkwdfaqmzjökcbucäbdslhwfssjvåjoxfbsltfvwgnvboegbrnboeghxöb 

The decrypted phrase is: 
asciiab¥dexyzg￧rmanäö￷äöuupo○ibmjcå￷äldhtc￲iwmtdå￶awmtddpw 

這裏是一個Java代碼:

所有的
public class VigenereCipher 
    { 
    public static void main(String[] args) throws IOException 
    { 
     String key = "Unicode"; 

     File file = new File("G:\\unicode.txt"); 

     FileInputStream fis = new FileInputStream(file); 
     byte[] fileBArray = new byte[fis.available()]; 
     fis.read(fileBArray); 

     String text = new String(fileBArray, "UTF-8"); 

     //String text = "Some simple text to check the decoding algorythm"; 
     System.out.println("The original text from file is: \n" + text); 
     String enc = encrypt(text, key); 
     System.out.println(enc + "\n"); 
     System.out.println("The decrypted phrase is: "); 
     System.out.println(decrypt(enc, key)); 
    } 

    // Encrypts a string 
    public static String encrypt(String message, String key) 
    { 
     message = StringToLowerCaseWithAllSymbols(message); 
     System.out.println("String that will be encoded is: \n" + message); 
     char messageChar, keyChar; 
     String encryptedMessage = ""; 
     for (int i = 0; i < message.length(); i++) 
     { 
      messageChar = shiftChar(message.charAt(i)); 
      keyChar = shiftChar(key.charAt(i % key.length())); 
      messageChar = (char) ((keyChar + messageChar) % 29); 
      messageChar = unshiftChar(messageChar); 
      encryptedMessage += messageChar; 
     } 
     System.out.println("\nThe encrypted string is: "); 
     return encryptedMessage; 
    } 

    // Decrypts a string 
    public static String decrypt(String cipher,String key) 
    { 
      char cipherChar, keyChar; 
      cipher = StringToLowerCaseWithAllSymbols(cipher); 
      String decryptedMessage = ""; 
      cipher = cipher.toLowerCase(); 
      for (int i = 0; i < cipher.length(); i++) 
      { 
       cipherChar = shiftChar(cipher.charAt(i)); 
       keyChar = shiftChar(key.charAt(i % key.length())); 
       cipherChar = (char) ((29 + cipherChar - keyChar) % 29); 
       cipherChar = unshiftChar(cipherChar); 
       decryptedMessage += cipherChar; 
      } 
      return decryptedMessage; 
    } 

    // Prunes all characters not in the alphabet {A-Öa-ö} from a string and changes it to all lower  case. 
    public static String StringToLowerCaseWithAllSymbols(String s) 
    { 
      //s = s.replaceAll("[^A-Za-zåäöÅÄÖ]", ""); 
      // 's' contains all the symbols from my text 
      s = s.replaceAll("[^A-Za-zäöüÄÖÜßąęźżńłабвгдежэюя你好]", ""); 
      return s.toLowerCase(); 
     } 

    // Assigns characters a,b,c...å,ä,ö the values 1,2,3...,26,28,29. 
    private static char shiftChar(char c) 
    { 
      if (96 < c && c < 123) 
      { 
       c -= 97; 
      } 
      else if (c == 229) 
      { 
       c = 26; 
      } 
      else if (c == 228) 
      { 
       c = 27; 
      } 
      else if (c == 246) 
      { 
       c = 28; 
      } 
      return c; 
     } 

    // Undoes the assignment in shiftChar and gives the characters back their UTF-8 values. 
    private static char unshiftChar(char c) 
    { 
      if (0 <= c && c <= 25) 
      { 
       c += 97; 
      } 
      else if (c == 26) 
      { 
       c = 229; 
      } 
      else if (c == 27) 
      { 
       c = 228; 
      } 
      else if (c == 28) 
      { 
       c = 246; 
      } 
      return c; 
     } 
} 

回答

1

首先,你不想轉移:你想旋轉。假設我們正在使用英文字母。如果'A'+ 2是'C','Z'+ 2是什麼?當你實現Vigenere密碼時,你需要'Z'+ 2 =='B'。

我不會在Vigenere密碼程序中使用Unicode:我會用我自己的編碼,其中字母表的第一個字母表示爲零,第二個字母表示一個,依此類推。因此,對於我的英文例子,代碼('A')==> 0,代碼('B')==>,...代碼('Z')==> 26。

然後我的旋轉功能如下:

int rotate(Alphabet alphabet, int code, int amount) { 
    return (code + amount) % alphabet.getLength(); 
} 

所以:

rotate(english, code('A'), 2) ==> (0 + 2)%26 == 2, (the code for 'C'), and 
rotate(english, code('Z'), 2) ==> (25 + 2)%26 == 1, (the code for 'B'). 
+0

好吧,我看..如果我有英語,俄語等符號,我需要爲所有人創造字母表他們? – TomatoLion 2014-10-12 17:31:20

+0

@ Kate21,我就是這麼做的。我可能會創建一個帶有方法的'Alphabet'接口,用於在自定義編碼和Unicode之間進行轉換,然後爲每種語言創建一個實現Alphabet的類。 – 2014-10-12 18:50:08