2013-01-05 2 views
0

어제 다음 질문을했지만 실제 문제에 대한 세부 정보가 실제로 포함되지 않았기 때문에 많은 관심을받지 못했습니다. 내가 당신에게 무슨 일이 일어나고 있는지에 대한 명확한 통찰력을 제공하기 위해 가능한 한 많은 내 문제를 분석하려고합니다UTF-8이 아닌 Cp1252 인코딩에서 Simplified DES를 잘 구현 한 이유는 무엇입니까?

Eclipse:Using UTF-8 encoding in the text editor make the Strings not work properly, how can I fix that?

.

나는 교육 목적으로 Simplified DES 알고리즘을 구현하기로되어있는 대학 프로젝트를 가지고 있습니다. 이 알고리즘은 8 비트 데이터를 암호화하기 위해 10 비트 키를 사용하는 암호화 알고리즘입니다.

구현시 모든 문자열을 암호화하고 싶습니다.

그래서 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 인 기본 인코딩을 사용합니다. 나는 문자열을 암호화하기 위해 노력하고 다음과 같은 결과를 얻었다 :

나는 각 문자열의 모든 데이터를 표시하기 위해 다음 함수를 생성 된 데이터를 I 암호화 할 때마다 실제 비트 표현을보고 암호를 해독하기 위해
Initial Text: INFO BOB 57674 
Encrypted Text: ÅO [áa[aá»j×jt 
Decrypted Text: INFO BOB 57674 

예상대로 모든 것이 작동처럼

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 

이 보인다 :

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(); 
} 

그래서 나는 다음과 같은 결과를 얻었다. 그래도 코드 편집기에서 그리스 문자를 지원하려면 인코딩을 UTF-8로 변경해야했습니다.

다시 모든 것을 실행 한 후, 나는 다음과 같은 결과를 얻었다 : 해독 된 텍스트의 일부 단어는 예를 NFOBOB에 대해 올바르게 표시되는 방법을

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

알 수 있습니다. 이클립스가 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 문자열에 더 많은 바이트를 추가하는 것 같습니다. 그러나 나는 왜 그런지 잘 모르겠다.초기 텍스트에 같은 크기의 바이트가있는 것 같습니다. 그렇다면이 바이트가 암호화 후에 추가되고 왜 더 많은 부분이 해독 후에 추가됩니까?

제공되는 도움에 감사드립니다. 미리 감사드립니다.

답변

4

String.getBytes()을 수행 할 때마다 플랫폼 기본 인코딩을 사용하여 문자를 바이트로 변환합니다. String에 플랫폼의 기본 인코딩을 사용하여 표현할 수없는 문자가 포함되어 있으면 정보가 손실됩니다. UTF8 : string.getBytes("UTF8")과 같이 지구상의 모든 캐릭터를 지원하는 명시 적 인코딩을 사용하십시오.

마찬가지로, new String(bytes)을 수행하면 플랫폼의 기본 인코딩을 사용하여 바이트를 문자로 변환합니다. 바이트가 실제로 다른 인코딩을 사용하여 텍스트로 인코딩 된 텍스트이거나 문자가 아닌 순수한 바이너리 정보 인 경우 정보도 잃게됩니다.

암호화는 2 진 연산입니다. 바이트를 취하여 다른 바이트를 반환합니다. 모든 바이트가 유효한 문자를 나타내지 않으므로 인코딩이 무엇이든간에 맹목적으로 바이트를 문자로 변환 할 수 없습니다. 바이너리 정보 (암호화 된 텍스트 등)를 String으로 변환하려면 Hex 또는 Base64 인코딩을 사용하십시오.

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

그리고 암호 해독 과정은 대칭이어야한다 :

그래서 암호화 프로세스가 있어야한다 (그는 Findbugs처럼`getBytes를 사용하여이 결함을 (정적 코드 분석 도구를 사용하는 경우,

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

진정한)'대신'getBytes (String)')가 즉시보고됩니다. –

+2

큰 차이는 아니지만 [StandardCharsets] (http://docs.oracle.com/javase/7/docs/api/java/nio/charset/StandardCharsets.html) 유형은 이제 다음에서 사용할 사전 정의 된 변수를 제공합니다. 형태 보증 된 메소드/생성자. – McDowell

+0

귀하의 명확한 설명을 주셔서 대단히 감사합니다, 내 문제가 마침내 해결되었습니다! – ksm001