我正在尝试构建一个程序,该程序将ascii值从32到126的字符转换为9个空格以对其进行加密。然后我想解密它。它成功解密了大多数值,但最后一组没有。这是我的代码如下:
intent.putExtra("names", (Serializable) names);
答案 0 :(得分:0)
我看到这里发生了几件事。
第一个是SIZE
是95,但是您要改写94。这将导致两个不同的纯文本字符映射到相同的加密字符。
要了解decrypt
的问题,请想象一下,当编码字符为37时会发生什么。在调用decrypt
之前减去32,得到5。(为什么不在{{1 }}?)然后减去9,得到-4。接下来,mod 94仍然为-4。然后,您将32加到28,超出了您的允许范围。
您应该做的而不是减去9是加85,即94(我认为您的数字错了,但是让我们继续吧)减9。现在不是90,而是-90。然后您将mod 94(仍为90),然后加32以获得122,这在您允许的范围内。
答案 1 :(得分:0)
除了两个小问题,您的算法还可以。第一个缺陷是模运算必须考虑字母的所有字符,即95,而不是Willis在其回答中已经解释的94。
第二个问题是您使用了错误模运算符。在解密期间,术语(val - 9)
可以变为负数。但是,对于负数,模运算的数学定义与许多编程语言(包括Java)中的定义不同。在凯撒密码算法中,数学模运算符是引用的,因此必须在实现中使用。另请参阅:Encrypting/Decrypting a string using a Affine cipher using the original 128 ASCII table
可以使用Java模运算符%
来定义数学模运算符,如下所示:
private static int mod(int a, int b) {
return ((a % b) + b) % b;
}
或者,可以使用方法int Math.floorMod(int a, int b)
。另请参阅:https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Math.html#floorMod(int,int)
要使用此mod
运算符(以及适当的除数95
)来替换encrypt
方法中的
return ((val + 9) % 94) + 32;
使用
return mod(val + 9, 95) + 32;
以及您的decrypt
方法
return ((val - 9) % 94) + 32;
使用
return mod(val - 9, 95) + 32;
然后输出变为:
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 { | } ~
现在,纯文本和解密文本匹配,并且在加密文本中,纯文本的所有字符都移位了9。