你好,evrybody,读过这个!

我需要在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;
        }
}

最佳答案

首先,您不想移动:您想旋转。假设我们正在使用英文字母。如果“ A” +2是“ C”,那么“ Z” +2是什么?实施Vigenere密码时,您需要'Z'+ 2 =='B'。

我不会在Vigenere密码程序中使用Unicode:我将使用自己的编码,其中字母的第一个字母用零表示,第二个字母用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').

10-08 19:37