Алгоритм не будет правильно шифровать / дешифровать - PullRequest
0 голосов
/ 21 февраля 2019

Я протестировал приведенный ниже код со всеми значениями ASCII от 64 до 90 включительно (все заглавные буквы) и скорректировал соответствующим образом, вместо:

for(int i = 0 ; i < c.length(); i++){
      info[i] = ((int)c.charAt(i) - 32);
  }

Я бы заменил 32 на 64 (поэтому значение ASCIIA будет сохранять в массиве как 0).Кроме того, в моих функциях шифрования и дешифрования я бы заменил 95 на 26 (26 букв).

Однако, если я применю это ко всем значениям между 32-126 включительно (95 символов) и соответствующим образом скорректирую значения, значения станут неправильными, и я не знаю почему.Вот моя основная функция ниже (обратите внимание, что формула, используемая в шифровании и дешифровании, является лишь примером, который я использовал, и я планирую изменить значения позже):

public static void main(String[] args) {

  String c = "sd344rf"; // could be any set of characters within the range
  int[] e = new int[c.length()]; // encrypted set
  int[] d = new int[c.length()]; // decrypted set

  int[] info = new int[c.length()];
  for(int i = 0 ; i < c.length(); i++){
      info[i] = ((int)c.charAt(i) - 32);
  }

  for(int i = 0; i < c.length(); i++){
      e[i] = encryption(info[i]);
  }

  for(int i = 0; i < c.length(); i++){
      d[i] = decryption(e[i]);
  }

  display(info);
  System.out.println();
  display(e);
  System.out.println();
  display(d);

}

public static int encryption(int x){
    return mod(3*x + 9,95);
}

public static int decryption(int x){
   return mod(9*x - 3,95);
}

public static void display(int[] arr){
    for(int i = 0; i < arr.length; i++){
      System.out.print(arr[i] + " ");
    }
}
}

1 Ответ

0 голосов
/ 21 февраля 2019

Очевидно, вы пытаетесь реализовать шифр affine .Для аффинного шифра шифрование

y = mod(n * x + s, m)

и дешифрование

x = mod(ni * (y - s), m)

с

x: Value of the character to encrypt
y: Value of the encrypted character
m: Number of characters in the underlying alphabet
n, s: Key of the encryption

n и s должно быть выбрано так, чтобыони между 0 и m - 1 включительно.Кроме того, n должен быть выбран так, чтобы n и m были взаимно простыми.ni является модульным мультипликативным обратным n по модулю m и определяется как n*ni mod m = 1.

Это более подробно объясняется в https://en.wikipedia.org/wiki/Affine_cipher.


Еслизначения u, v, связанные с символами, не начинаются с 0 значения должны быть сдвинуты на смещение, равное значению первого символа (при условии, что пробелов нет), и формулы становятся

x = u - offset
y = v - offset 

v = mod(n * (u - offset) + s, m) + offset
u = mod(ni * ((v - offset) - s), m) + offset

Таким образом, вы должны заменить main -метод

info[i] = ((int)c.charAt(i) - 32);

на

info[i] = (int)c.charAt(i);

encryption -метод становится:

public static int encryption(int u) {
    return mod(n * (u - offset) + s, m) + offset;
}

и decryption -метод

public static int decryption(int v) {
    return mod(ni * ((v - offset) - s), m) + offset;
}

с полями

private static int m = <Number of the characters in the alphabet>;
private static int n = <Key (factor)>;   // n between 0 and m-1 and moreover, n and m have te be coprime
private static int s = <Key (summand)>;  // s between 0 and m-1
private static int offset = <Value of the first character of the alphabet>;
private static int ni = <Modular multiplicative inverse of n modulo m>;

Кроме того, для операции mod используется следующий метод(см. Программа шифрования / дешифрования не работает должным образом ):

private static int mod(int a, int b) {
    return ((a % b) + b) % b;
}

Пример 1: Прописные буквы A - Z:

private static int m = 'Z' - 'A' + 1;    // 26
private static int n = 3;                // Choose e.g. n = 3: n = 3 < 26 - 1 = 25 and moreover, 3 and 26 are coprime
private static int s = 9;                // Choose e.g. s = 9: s = 9 < 26 - 1 = 25
private static int offset = 'A';         // 65
private static int ni = 9;               // 3*9 mod 26 = 1

Тест:

String c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

Вывод (с символами вместо их значений):

Plain text:     ABCDEFGHIJKLMNOPQRSTUVWXYZ
Encrypted text: JMPSVYBEHKNQTWZCFILORUXADG
Decrypted text: ABCDEFGHIJKLMNOPQRSTUVWXYZ

Пример 2. Все символы от 32 (пробел) до 126 (~),включительно:

private static int m = '~' - ' ' + 1;    // 95
private static int n = 3;                // Choose e.g. n = 3: n = 3 < 95 - 1 = 94 and moreover, 3 and 95 are coprime
private static int s = 9;                // Choose e.g. s = 9: s = 9 < 95 - 1 = 94
private static int offset = ' ';         // 32
private static int ni = 32;              // 3*32 mod 95 = 1

Тест:

String c = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; 

Вывод (с символами вместо их значений):

Plain text:      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
Encrypted text: ),/258;>ADGJMPSVY\_behknqtwz}!$'*-0369<?BEHKNQTWZ]`cfilorux{~"%(+.147:=@CFILORUX[^adgjmpsvy| #&
Decrypted text:  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...