Я работаю над реализацией шифровального / дешифрующего шифра, который называется Transposition Cipher. По сути, вход имеет операцию («E» для шифрования, «D» для дешифрования), ключ и сообщение, которые должны быть заполнены в 2d массиве на основе алфавитного порядка ключей. Выходом является зашифрованная / расшифрованная строка. Пустые пробелы в сетке должны быть заполнены'@'.
. Это работает для обычных случаев, но '@' не заполняет пробелы должным образом, когда:
- ключ имеет повторяющиеся символы и / или длиннее открытого текста (он не шифруется / не дешифруется правильным образом)
ex input: E COMPUTERSCIENCE HELLO WORLD
ожидается вывод: HD@O@@@L@ELRLWO
мой вывод: HLOWORL @@ E@D@L@
- длина ключа равна открытому тексту
ex input: D КОМПЬЮТЕРНАЯ НАУКА HD@O@@@L@ELRLWO
ожидаемый результат: HELLOWORLD @@@@@
мой вывод: HEWD@O@@@ROL@LL
Я прикрепил свой код ниже.
Спасибо большое!
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
public class TranspositionCipher {
private String line;
private String[] arr;
private String oper;
private String text;
private String key;
public TranspositionCipher(String line, String[] array, String oper, String text, String key) {
this.line = line;
this.arr = array;
this.oper = oper;
this.text = text;
this.key = key;
}
public static String encryptCT(String key, String text) {
int[] arrange = arrangeKey(key);
int lenkey = arrange.length;
int lentext = text.length();
int numRows;
if (lenkey > lentext) {
numRows = 1;
} else {
numRows = (int) Math.ceil((double) lentext / lenkey);
}
char[][] grid = new char[numRows][lenkey];
int z = 0;
for (int x = 0; x < numRows; x++) {
for (int y = 0; y < lenkey; y++) {
if (z < lentext) {
grid[x][y] = text.charAt(z);
z++;
} else {
grid[x][y] = FillEmptySpace();
}
}
}
String enc = "";
for (int x = 0; x < lenkey; x++) {
for (int y = 0; y < lenkey; y++) {
if (x == arrange[y]) {
for (int a = 0; a < numRows; a++) {
enc = enc + grid[a][y];
}
}
}
}
return enc;
}
public static String decryptCT(String key, String text) {
int[] arrange = arrangeKey(key);
int lenkey = arrange.length;
int lentext = text.length();
int numRows;
if (lenkey > lentext) {
numRows = 1;
} else {
numRows = (int) Math.ceil((double) lentext / lenkey);
}
String regex = "(?<=\\G.{" + numRows + "})";
String[] get = text.split(regex);
char[][] grid = new char[numRows][lenkey];
for (int x = 0; x < lenkey; x++) {
for (int y = 0; y < lenkey; y++) {
if (arrange[x] == y) {
for (int z = 0; z < numRows; z++) {
grid[z][y] = get[arrange[y]].charAt(z);
}
}
}
}
String dec = "";
for (int x = 0; x < numRows; x++) {
for (int y = 0; y < lenkey; y++) {
dec = dec + grid[x][y];
}
}
return dec;
}
public static char FillEmptySpace() {
return '@';
}
public static int[] arrangeKey(String key) {
String[] keys = key.split("");
Arrays.sort(keys);
int[] num = new int[key.length()];
int count = 0;
for (int i = 0; i < key.length(); i++) {
for (int j = i + 1; j < key.length(); j++) {
if (key.substring(i, i + 1).equals(key.substring(j, j + 1))) {
count++;
}
}
}
if (count > 0) {
ArrayList<Integer> numList = new ArrayList<>();
for (int k = 0; k < key.length(); k++) {
char c = key.charAt(k);
for (int l = 0; l < key.length(); l++) {
if (!numList.contains(l)) {
if (key.charAt(l) == c) {
numList.add(l);
}
}
}
}
for (Integer i : numList) {
num[i] = numList.get(i);
}
} else {
for (int x = 0; x < keys.length; x++) {
for (int y = 0; y < key.length(); y++) {
if (keys[x].equals(key.charAt(y) + "")) {
num[y] = x;
break;
}
}
}
}
return num;
}
public static void main(String[] args) throws FileNotFoundException {
Scanner fileIn = new Scanner(new File("input.txt"));
while (fileIn.hasNextLine()) {
String line = fileIn.nextLine();
String[] arr = line.split(" ");
String oper = arr[0];
String text = "";
for (int i = 2; i < arr.length; i++) {
text += arr[i];
}
String key = arr[1];
text = text.replaceAll("'", "");
TranspositionCipher crypt = new TranspositionCipher(line, arr, oper, text, key);
if (crypt.oper.equals("E")) {
System.out.println(encryptCT(key, text).toUpperCase());
}
if (crypt.oper.equals("D")) {
System.out.println(decryptCT(key, text).toUpperCase());
}
}
}
}```