Encryption/decryption program not working properly

雨燕双飞 提交于 2020-01-06 05:33:25

问题


I am trying to build a program that takes the characters with ascii values from 32 to 126 and shifting them over by 9 spaces to encrypt them. Then I want to decrypt it. It successfully decrypts most of the values but the last bunch do not. Here's my code below:

public static void main(String[] args) {

    final int SIZE = 95; // total # of ascii vals being used
    int[] availableChars = new int[SIZE];
    int[] ePhrase = new int[SIZE];
    int[] dePhrase = new int[SIZE];

    for(int i = 0; i < SIZE; i++){
        availableChars[i] = (i + 32);
    }

    for(int i = 0; i < SIZE; i++){
        ePhrase[i] = encrypt(availableChars[i] - 32);
    }

    for(int i = 0; i < SIZE; i++){
        dePhrase[i] = decrypt(ePhrase[i] - 32);
    }
    System.out.print("\n");

    for(int i = 0; i < SIZE; i++){
        System.out.print(i + " ");
    }
    System.out.print("\n");

    for(int i = 0; i < SIZE; i++){
        System.out.print((char)availableChars[i] + " ");
        if(i >= 10){
            System.out.print(" ");
        }
    }

    System.out.print("\n");

    for(int i = 0; i < SIZE; i++){
        System.out.print((char)ePhrase[i] + " ");
        if(i >= 10){
            System.out.print(" ");
        }
    }   

    System.out.print("\n");

    for(int i = 0; i < SIZE; i++){
        System.out.print((char)dePhrase[i] + " ");
        if(i >= 10){
            System.out.print(" ");
        }
    }

}

public static int encrypt(int val){
    return ((val + 9) % 94) + 32;
}

public static int decrypt(int val){
    return ((val - 9) % 94) + 32;
}

回答1:


I see a couple of things going on here.

The first one is that SIZE is 95 but then you're modding with 94. That's going to result in two different plaintext characters mapping to the same encrypted character.

To understand the issue with decrypt, imagine what happens when the encoded character is, say, 37. You subtract 32 before calling decrypt, giving 5. (Why not do this in decrypt?) Then you subtract 9 giving -4. Next, mod 94 gives still -4. Then you add 32 giving 28, which is outside your allowed range.

What you should do instead of subtract 9 is add 85, which is 94 (your number that I think is wrong, but let's go with it) minus 9. Instead of -4 you now have 90. Then you mod 94 (still 90) and add 32 to get 122, which is within your allowed range.




回答2:


Apart from two minor issues your algorithm is OK. The first flaw is that the modulo-operation must consider all characters of the alphabet and that is 95 instead of 94 as already explained by Willis in his answer.

The second problem is that you use a wrong modulo-operator. During decryption the term (val - 9) can become negative. However, for negative numbers the mathematical definition of the modulo-operation differs from the definition in many programming languages (including Java). In the Caesar-cipher-algorithm the mathematical modulo-operator is referred to and thus, has to be used in the implementation. See also: Encrypting/Decrypting a string using a Affine cipher using the original 128 ASCII table

The mathematical modulo-operator can be defined in terms of the Java modulo-operator % as follows:

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

Alternatively, the method int Math.floorMod(int a, int b) can be used. See also: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Math.html#floorMod(int,int)

To use this mod-operator (and also the proper divisor 95) replace in your encrypt-method

return ((val + 9) % 94) + 32;

with

return mod(val + 9, 95) + 32;

and in your decrypt-method

return ((val - 9) % 94) + 32;

with

return mod(val - 9, 95) + 32;

Then the output becomes:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 
  ! " # $ % & ' ( ) *  +  ,  -  .  /  0  1  2  3  4  5  6  7  8  9  :  ;  <  =  >  ?  @  A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  [  \  ]  ^  _  `  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  {  |  }  ~  
) * + , - . / 0 1 2 3  4  5  6  7  8  9  :  ;  <  =  >  ?  @  A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  [  \  ]  ^  _  `  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  {  |  }  ~     !  "  #  $  %  &  '  (  
  ! " # $ % & ' ( ) *  +  ,  -  .  /  0  1  2  3  4  5  6  7  8  9  :  ;  <  =  >  ?  @  A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  [  \  ]  ^  _  `  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  {  |  }  ~  

Now, plain and decrypted text match and all characters of the plain text are shifted by 9 in the encrypted text.



来源:https://stackoverflow.com/questions/54779199/encryption-decryption-program-not-working-properly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!