BigInteger如何解释字符串中的字节?

时间:2014-03-16 03:25:10

标签: java encryption encoding utf-8 biginteger

我正在开发一个程序,它是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

2 个答案:

答案 0 :(得分:2)

  

我试图理解明文通道是如何被数字解释的,允许它被加密。

这真的归结为理解这条线的作用:

   BigInteger plainText = new BigInteger(string.getBytes("UTF-8"));

让我们分解。

  1. 我们从字符串(string)开始。 Java字符串是表示为Unicode代码点的字符序列(以UCS-16编码...)。

  2. getBytes("UTF-8")然后将字符编码为字节序列,并在新分配的字节数组中返回它们。

  3. BigInteger(byte[])构造函数将该字节数组解释为数字。正如javadoc所说:

      

    将包含BigInteger的二进制补码二进制表示的字节数组转换为BigInteger。输入数组是   假设是大端字节顺序:最重要的字节是   在第0个元素中。

  4. 这里使用的方法不是给出一个有意义的有意义的数字,只是对应于字节编码的字符串。从字节数组到数字只是将字节视为一个位序列,表示2的补码形式的整数...这是现代硬件上整数的最常见表示。

    关键是从文本到(未加密的)BigInteger的转换是无损且可逆的。可以使用具有这些属性的任何其他转换。

    参考文献:


      

    我还不太明白为什么" test",116,101,115,116中的每个字符的UTF-8值如何组合在一起形成1952805748?

    1. 将数字116,101,115,116转换为十六进制。
    2. 将数字1952805748转换为十六进制
    3. 比较他们
    4. 看模式?

答案 1 :(得分:1)

答案在输出中,“test”被编码为4个字节的数组[116,101,115,116]。然后由BigInteger将其作为二进制整数表示。可以通过这种方式计算值

value = (116 << 24) + (101 << 16) + (115 << 8) + 116;