1

これを読んでいる皆さん、こんにちは!

JavaでVigenere暗号を実現する必要があります。読み取り、エンコード、およびデコードする .txt ドキュメントがあります。ここにあります:

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

私の問題は、文字を正しくシフトする方法がわからないことです。この表によると、ラテン文字には 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;
        }
}
4

1 に答える 1

1

まず第一に、シフトしたくない:回転したい. 英語のアルファベットを扱っているとします。「A」+2 が「C」の場合、「Z」+2 は何ですか? Vigenere 暗号を実装する場合は、'Z'+2=='B' が必要です。

Vigenere 暗号プログラムでは Unicode を使用しません。アルファベットの最初の文字が 0 で表され、2 番目の文字が 1 で表される独自のエンコーディングを使用します。したがって、私の英語の例では、code('A')==>0, code('B')==>, ... code('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').
于 2014-10-12T16:32:23.237 に答える