我正在开发一个实现 RSA 加密算法的程序,只是作为个人练习,它不会保护任何人的信息或任何东西。我试图了解如何对明文段落进行数字解释,从而对其进行加密。我知道大多数 UTF-8 字符最终只使用 1 个字节的空间,而不是人们可能认为的 2 个字节,但仅此而已。这是我的代码:
BigInteger ONE = new BigInteger("1");
SecureRandom rand = new SecureRandom();
BigInteger d, e, n;
BigInteger p = BigInteger.probablePrime(128, rand);
BigInteger q = BigInteger.probablePrime(128, rand);
BigInteger phi = (p.subtract(ONE)).multiply(q.subtract(ONE));
n = p.multiply(q);
e = new BigInteger("65537");
d = e.modInverse(phi);
String string = "test";
BigInteger plainText = new BigInteger(string.getBytes("UTF-8"));
BigInteger cipherText = plainText.modPow(e, n);
BigInteger originalMessage = cipherText.modPow(d, n);
String decrypted = new String(originalMessage.toByteArray(),"UTF-8");
System.out.println("original: " + string);
System.out.println("decrypted: " + decrypted);
System.out.println(plainText);
System.out.println(cipherText);
System.out.println(originalMessage);
System.out.println(string.getBytes("UTF-8"));
byte byteArray[] = string.getBytes("UTF-8");
for(byte littleByte:byteArray){
System.out.println(littleByte);
}
输出:
original: test
decrypted: test
1952805748
16521882695662254558772281277528769227027759103787217998376216650996467552436
1952805748
[B@60d70b42
116
101
115
116
也许更具体地说,我想知道这一行:
BigInteger plainText = new BigInteger(string.getBytes("UTF-8"));
“test”的每个字母都有一个值,并且在这里将它们逐字相加吗?比如 t=1,e=2,s=3,t=1 ,如果你从那个字符串中得到字节,你最终得到的是 7 还是这些值只是像 1231 一样放在一起?为什么
BigInteger plainText = new BigInteger(string.getBytes("UTF-8"));
输出 1952805748
最佳答案
I am trying to understand how a plaintext passage is being interpreted numerically, allowing it to be encrypted.
真正归结为理解这一行的作用:
BigInteger plainText = new BigInteger(string.getBytes("UTF-8"));
让我们分解一下。
我们从一个字符串 (
string
) 开始。 Java 字符串是表示为 Unicode 代码点(以 UCS-16 编码...)的字符序列。getBytes("UTF-8")
然后将字符编码为字节序列,并在新分配的字节数组中返回它们。BigInteger(byte[])
构造函数将该字节数组解释为数字。正如 javadoc 所说:Translates a byte array containing the two's-complement binary representation of a BigInteger into a BigInteger. The input array is assumed to be in big-endian byte-order: the most significant byte is in the zeroth element.
这里使用的方法并没有给出一个本质上有意义的数字,只是一个对应于字节编码字符串的数字。从字节数组到数字只是将字节视为一个位序列,以 2 的补码形式表示一个整数……这是现代硬件上最常见的整数表示形式。
关键是从文本到(未加密的)BigInteger 的转换是无损和可逆的。可以使用具有这些属性的任何其他转换。
引用资料:
- 2's Complement 上的维基百科页面代表
- UTF-8 上的维基百科页面文本编码方案
- javadoc
BigInteger(byte[])
- javadoc
String.getBytes(String)
Im still not quite understanding how the the UTF-8 values for each character in "test", 116,101,115,116 respectively come together to form 1952805748?
- 将数字 116,101,115,116 转换为十六进制。
- 将数字 1952805748 转换为十六进制
- 比较它们
看到模式了吗?
关于java - BigInteger 如何解释字符串中的字节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22432580/