gpt4 book ai didi

java - 使用原始 128 ASCII 表使用仿射密码加密/解密字符串

转载 作者:行者123 更新时间:2023-11-30 07:42:30 27 4
gpt4 key购买 nike

所以我正在尝试使用仿射密码来加密消息。我想使用所有 128 个 ASCII 字符来完成它。当涉及到特定字母 Q、R、S、T 和 U 时,我收到错误消息。它们没有正确转换回来并显示不正确的解密。知道发生了什么事吗?

加密信息

RUX[^adgjmpsvy|

解密消息

ABCDEFGHIJKLMNOP/.-,+VWXYZ

我的代码;

public class EncryptionProject {

public static void main(String[] args) {

StringBuilder s = new StringBuilder("ABCDEFGHIJKLMNOPQRSTUVWXYZ");

System.out.println("Encrypted Message");
StringBuilder encryptedMessage = affineEncryption(s);
System.out.print(encryptedMessage);

System.out.println("\nDecrypted Message");
StringBuilder decryptedMessage = affineDecryption(encryptedMessage);
System.out.print(decryptedMessage);
}

/* use affine cipher to encrypt message */
public static StringBuilder affineEncryption(StringBuilder s) {
StringBuilder encryption = new StringBuilder();
final int A = 3, B = 15, M = 128; // a * p + b (mod m)

/* loop through string and compute affine cipher */
for (int i = 0; i < s.length(); i++) {
encryption.append((char)((A * s.charAt(i) + B) % M));
}

return encryption;
}

/* decryption method */
public static StringBuilder affineDecryption(StringBuilder s) {
final int A = 43, B = 15, M = 128;
StringBuilder decryption = new StringBuilder();

/* loop through and undo affine cipher using inverse of A */
for (int i = 0; i < s.length(); i++) {
decryption.append((char)((A * Math.abs((s.charAt(i) - B))) % M));
}

return decryption;
}
}

最佳答案

问题的原因是对于负股息 a 和/或除数 n modulo operation 的数学定义通常可能与各自编程语言中的定义不同。

模运算的结果在数学上定义为 Euclidean division 的余数.该余数始终大于或等于零。对于正除数 n,余数由下式给出:

a mod n = a - n * floor(a/n) 

其中 floor(a/n)floor-function它给出小于或等于其输入的最大整数作为输出(我不考虑负除数 n 因为 n = 128 > 0 在问题中)。

正除数 n = 128 的示例,正​​除数 a = 559(上图)和负除数 a = -559 (下):

559 mod 128 = 559 - 128 * floor(559/128) = 559 - 128 * floor(4.37) = 559 -128 * 4 = 47
-559 mod 128 = -559 - 128 * floor(-559/128) = -559 - 128 * floor(-4.37) = -559 -128 * (-5) = 81

但是,在许多编程语言(包括 Java)中,使用不同的模运算定义(有时称为对称变体):

a mod n = a - n * trunc(a/n) 

此处,trunc(a/n) 表示商 a/n 向零舍入的截断除法。

正除数 n = 128 与正股息 a = 559(上图)和负股息 a = -559 的示例(下):

559 mod 128 = 559 - 128 * trunc(559/128) = 559 - 128 * trunc(4.37) = 559 -128 * 4 = 47      
-559 mod 128 = -559 - 128 * trunc(-559/128) = -559 - 128 * trunc(-4.37) = -559 -128 * (-4) = -47

正如您所见,数学定义和对称定义都为负股息提供了不同的结果。

问题的直接原因是,在仿射密码的公式中,数学 定义是指,而在您的代码中使用了对称 变体(因为 Java使用对称变体)。这可以通过字母 Q 的示例很好地证明:在您的代码中,字母 Q (= 81 dec) 被加密(A = 3, B = 15, M = 128) 到

(3 * 81 + 15) % 128 = 2

解密(A = 43, B = 15, M = 128)为

(43 * (2 - 15)) % 128 = -559 % 128

根据模变体,对称变体和数学变体的结果分别为 -4781(见上文)。由于代码中使用了对称变体,因此您会得到“错误”结果 -47

因此,解决方案是将代码中的模运算切换为数学定义。这可以通过以下公式实现:

a mMod n  = ((a sMod n) + n) sMod n

其中 mModsMod 分别表示数学和对称模运算符。为此,定义一个新方法:

private static int mathematicalMod(int a, int n) {
return ((a % n) + n) % n;
}

并替换为affineEncryption-method

encryption.append((char)((A * s.charAt(i) + B) % M));

encryption.append((char)mathematicalMod(A * s.charAt(i) + B, M));

affineDecryption 方法中

decryption.append((char)((A * Math.abs((s.charAt(i) - B))) % M));

decryption.append((char)mathematicalMod(A * (s.charAt(i) - B),  M));

请注意,在后一个替换中 Math.abs 方法也被删除,因为它不属于 affine-cipher-decrypt-algorithm .

有了这些改变,以及下面的输入

StringBuilder s = new StringBuilder("AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0=1!2\"34$5%6&7/8(9)^`+*#'-_.:,;<>\\[]~{}|@");

控制台中的输出变为:

enter image description here

在 Java 中还有一个对称变体的实现:int Math.floorMod(int a, int n) 当然,也可以使用它来代替自定义实现 int mathematicalMod(int a, int n).

关于java - 使用原始 128 ASCII 表使用仿射密码加密/解密字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54583472/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com