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 表示,第二个字母用 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 回答