Привет, кто читает это!Vigenere Cipher java UTF-8
Мне нужно реализовать шифр Vigenere на Java. У меня есть .txt документ, который я буду читать, кодировать и декодировать. Вот оно:
ASCII abcde xyz
German äöü ÄÖÜ ß
Polish ąęźżńł
Russian абвгдеж эюя
CJK 你好
Моя проблема заключается в том, что я не знаю, как правильно перенести символы, согласно this table латинских букв имеют коды от 0061 до 007A. Немецкие, которые мне нужны: 00C0 - 00FF, польский: 0100-017F, русский 0430-044F, и я не заинтриговал китайский.
Как я могу указать unshiftChar
и shiftChar
, чтобы сделать это подставкой? Теперь мой вход выглядит следующим образом:
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¥dexyzgrmanäöäöuupo○ibmjcåäldhtciwmtdå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;
}
}
Хорошо, я вижу .. А если у меня есть английский, русский и т.д. символов, мне нужно создать алфавит для всех из них? – TomatoLion
@ Kate21, вот как бы я это сделал. Я бы, вероятно, создал интерфейс «Alphabet» с методами для преобразования между пользовательской кодировкой и Unicode, а затем я бы сделал один класс, который «реализует алфавит» для каждого языка. –