将int转换为String,然后使用XOR对其进行加密

use*_*067 2 java string encryption int character-encoding

我正在尝试将整数转换为字符串,然后使用XOR加密对字符串进行加密.但是当我再次解密我的Strin时,我得到了一个不同的答案,即我在加密之前输入的字符串,我不知道我做错了什么?

public class Krypte {
public static void main (String [] args) {
    int i = 12345;

    String k = Integer.toString(i);
    String G = secure(k.getBytes());
    System.out.println("Encrypted: " + G);

    String U = secure(G.getBytes());
    System.out.println("Decrypted: " + U);
    int X = Integer.parseInt(U);
    System.out.println("As an int: " + X);

}

public static String secure(byte[] msg) {
    // Variables
    int outLength = msg.length;
    byte secret = (byte) 0xAC; // same as 10101100b (Key)
    // XOR kryptering
    for (int i = 0; i < outLength; i++) {
        // encrypting each byte with XOR (^)
        msg[i] = (byte) (msg[i] ^ secret);
    }
    return new String(msg);
}
}
Run Code Online (Sandbox Code Playgroud)

rai*_*7ow 5

charbyte类型之间存在微妙(但非常重要)的区别.考虑一下:

class Krypte {
    public static void main (String [] args) {
        int i = 12345;
        String k = Integer.toString(i);
        System.out.println("Before: " + k);    
        String G = secure(k.toCharArray());
        System.out.println("Encrypted: " + G);
        String U = secure(G.toCharArray());
        System.out.println("Decrypted: " + U);
        int X = Integer.parseInt(U);
        System.out.println("As an int: " + X);
    }

    public static String secure(char[] msg) {
        // Variables
        int outLength = msg.length;
        byte secret = (byte) 0xAC; // same as 10101100b (Key)
        // XOR kryptering
        for (int i = 0; i < outLength; i++) {
            // encrypting each byte with XOR (^)
            System.out.println("Byte before: " + msg[i]);
            msg[i] = (char) (msg[i] ^ secret);
            System.out.println("Byte after: " + msg[i]);
        }
        return new String(msg);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是有效的(证明),因为用字节对一些字符值进行异或将(很可能)给你一个有效的字符.

不要让我们看看原始代码段中发生了什么- 通过将此调试输出添加到secure方法的主循环中:

 System.out.println("Byte before: " + msg[i]);
 msg[i] = (byte) (msg[i] ^ secret);
 System.out.println("Byte after: " + msg[i]);
Run Code Online (Sandbox Code Playgroud)

输出将是:

Byte before: 49
Byte after: -99
Byte before: 50
Byte after: -98
Byte before: 51
Byte after: -97
Byte before: 52
Byte after: -104
Byte before: 53
Byte after: -103
Run Code Online (Sandbox Code Playgroud)

这很好:第一个getBytes函数使用平台的默认字符集将给定的字符串编码为字节数组.字符被编码为字节值; 变得等等'1'49'2'50

然后我们用我们的密钥对这些值进行异或 - 得到这个字节序列:

-99 -98 -97 -104 -103
Run Code Online (Sandbox Code Playgroud)

最后一步似乎很简单:我们只是从这个字节序列中生成(并返回)一个新的String,这里可能出错?但事实上,这是风扇受到打击的最佳步骤.)

请参阅,String构造函数尝试使用平台的默认字符集来处理此字节序列.实际上,对于某些字符集,这些字节代表一系列有效字符就好了 - 但不适用于UTF-8!

......你可能已经猜到接下来会发生什么.对于每个'不可解码的'字节序列,如此处所述,第一个字节被转换为所谓的替换字符,其他字符被重试.在这个特定的例子中,第一次secure调用返回的字符串中有五个失败的迹象.

对此字符串进行解码很有意义 - 因为它不存储有关目标字符串的任何信息(长度除外).这就是原始代码最终失败的原因.