为什么在编码的Cp1252而不是下UTF-8的工作我的实现简化DES的罚款?(Why is my i

2019-10-17 13:39发布

昨天我提出以下问题,但它并没有因为这样的事实,我并没有真正包括有关我的实际问题的任何细节得到重视。

月蚀:在文本编辑器使用UTF-8编码进行字符串不能正常工作,我该如何解决呢?

我会尝试尽可能多的分析,以给你这是怎么回事豁然开朗我的问题。

我在那里我应该实现简化DES算法用于教育目的一所大学的项目。 该算法是使用一个10位的密钥以加密的8位数据的加密算法。

在实现,我想包括加密的字符串。

所以我写的代码,8位的加密和它的工作完美的罚款对各种输入。 为了包括字符串加密支持我所使用的函数String.getBytes()保存在变量中的字符串的所有字节byte[] data

然后我跟着此逻辑:

int i;
for(i=0; i< data.length; i++)
    data[i] = encrypt(data[i]);

和解密我遵循了这一逻辑:

int i;
for(i=0; i< data.length; i++)
    data[i] = encrypt(data[i]);

这是在实际的代码main功能

public static void main(String[] args){

    short K = (short) Integer.parseInt("1010010001",2);
    SDEncryption sdes = new SDEncryption(K); //K is the 10 bit key

    String test = "INFO BOB 57674";

    //let's encrypt the String test
    String enc = sdes.encrypt(test.getBytes());

    //let's decrypt the encrypted String of the initial String
    String dec = sdes.decrypt(enc.getBytes());
}

通过使用默认的编码,这为CP1252,。 我试图加密字符串,得到了以下结果:

Initial Text: INFO BOB 57674
Encrypted Text: ÅO [áa[aá»j×jt
Decrypted Text: INFO BOB 57674

为了看到实际位表示每个I加密时间和解密数据I,以便显示每个字符串的所有数据创建了以下功能:

public void show(byte[] data){
    //εμφάνιση των 
    //note how the Greek letters aren't displayed at all under Cp1252

    int i;
    for(i=0;i<data.length;i++){

        short mask = (short) (1<<7); //10000000
        while(mask>0){
            if((data[i]&mask) == 0)
                System.out.print("0");
            else
                System.out.print("1");

            mask = (short) (mask >> 1);
        }
        if(i < data.length - 1){

            System.out.print(" ");
        }
    }
    System.out.println();
}

所以,我得到了以下结果:

Initial Text(binary): 01001001 01001110 01000110 01001111 00100000 01000010 01001111 01000010 00100000 00110101 00110111 00110110 00110111 00110100
Encrypted Text(binary): 11000101 01001111 00100000 01011011 11100001 01100001 01011011 01100001 11100001 10111011 01101010 11010111 01101010 01110100
Decrypted Text(binary): 01001001 01001110 01000110 01001111 00100000 01000010 01001111 01000010 00100000 00110101 00110111 00110110 00110111 00110100

好像一切都按预期工作。 为了支持在代码编辑器希腊字母,虽然,我不得不改变编码为UTF-8。

再次运行一切后,我得到了以下结果:

Initial Text: INFO BOB 57674
Encrypted Text: �O [�a[a�j�jt
Decrypted Text: ���NFO���BOB���7���74

请注意如何解密文本的某些单词显示正确,例如NFOBOB 。 在我看来,仿佛有某种同位操作的问题,因为如果Eclipse不承认跟随UTF-8的规则位的序列。

以下是二进制形式的结果:

Initial Text(binary): 01001001 01001110 01000110 01001111 00100000 01000010 01001111 01000010 00100000 00110101 00110111 00110110 00110111 00110100
Encrypted Text(binary): 11101111 10111111 10111101 01001111 00100000 01011011 11101111 10111111 10111101 01100001 01011011 01100001 11101111 10111111 10111101 01101010 11101111 10111111 10111101 01101010 01110100
Decrypted Text(binary): 11101111 10111111 10111101 11101111 10111111 10111101 11101111 10111111 10111101 01001110 01000110 01001111 11101111 10111111 10111101 11101111 10111111 10111101 11101111 10111111 10111101 01000010 01001111 01000010 11101111 10111111 10111101 11101111 10111111 10111101 11101111 10111111 10111101 00110111 11101111 10111111 10111101 11101111 10111111 10111101 11101111 10111111 10111101 00110111 00110100

现在,我可以清楚地看到问题的矿石。 这似乎是UTF-8增加了更多的字节字符串。 但是我不知道为什么。 我指的是初始文本似乎有那么为什么这些字节拿到加密后添加,更被解密后添加了相同的字节数量?

我将不胜感激提供的任何帮助。 先感谢您!

Answer 1:

每次你做String.getBytes()您隐用你的平台默认编码字符转换为字节。 如果字符串包含不能使用平台的缺省编码表示的字符,你失去的信息。 因此,使用显式编码支持地球上的每一个字符,像UTF8: string.getBytes("UTF8")

同样,当你new String(bytes) ,你用你的平台默认编码的字节转换成字符。 如果字节实际上是在文字使用另一种编码编码的,或者不是字符可言,而是纯粹的二进制信息,你也将失去信息。

加密是一个二元运算。 这需要字节并返回其他字节。 你不能一味地变换成字节字符,不管编码是,因为不是所有的字节表示一个有效的字符。 如果你想为二进制信息(如加密文本)转换为字符串,使用十六进制或Base64编码。

所以加密过程应该是:

String clearText = ...:
byte[] clearTextAsBytes = clearText.getBytes("UTF8");
byte[] encryptedBinary = encrypt(clearTextAsBytes);
String encryptedBinaryAsPrintableChars = toBase64(encryptedBinary);

和解密过程应该是对称的:

String encryptedBinaryAsPrintableChars = ...;
byte[] encryptedBinary  = fromBase64(encryptedBinaryAsPrintableChars);
byte[] decryptedTextAsBytes = decrypt(encryptedBinary);
String decryptedText = new String(decryptedTextAsBytes, "UTF8");


文章来源: Why is my implementation of Simplified DES working fine under Cp1252 encoding but not under UTF-8?