2014-03-27 2 views
9

나는 주어진 문자열 str을 함께 다음을 수행 앱 쓰고 있어요 :디코딩 및 인코딩 문제. android.util. * 및 java.util. *의 Base64 클래스 구현이 다릅니 까?

encode(encrypt(encode(stringToBytearray(str)))); 

서버가 Base64로 인코딩 된 문자열을 수신, 디코딩 후입니다 -> 복호화 -> 디코딩에서 전송 된 문자열 str을받을 앱.

불행하게도이 모든 문자열에 대한 작업을 나던 긴 문자열이 긴 Base64로 문자열로 이어질 내 서버는 다음과 같은 예외가 발생합니다 :

Exception in thread "main" java.lang.IllegalArgumentException: Illegal base64 character 5b 
at java.util.Base64$Decoder.decode0(Base64.java:714) 
at java.util.Base64$Decoder.decode(Base64.java:526) 
at Main.decode(Main.java:113) 
at Main.main(ain.java:33) 

문자열의 형식은 "가를 [문자열, 문자열, ..., 의 "없이"문자열].

내가 (나는 아직 길이를 정량화 어차피 죄송합니다) 너무 오래하지 않은 문자열을 위해, 위에서 언급 한 것처럼,이 작품. 그래서 나는 바로 그것을 구현 생각합니다.

무슨 이상한 내가 그것을 보내지 않으면,하지만 해독 (해독 (디코딩 (strin gToBytearray (str))))); 장치 자체의 문자열은 모두 완벽하게 작동합니다.

내 설정

:

그것이 JDK 7, 일식 (ADT-번들, 안드로이드 개발) (윈도우 7)

JDK (8), 일식 ('정상'자바) (리눅스 (분투))인가 두 클래스 (Base64)가 서로 다르게 구현 되었기 때문에? 그렇다면 어떻게 작동시킬 수 있습니까?

여기 인코딩/디코딩 방법은 다음과 같습니다

인코딩 (장치 : 윈도우 7, ADT-번들, 안드로이드 데브, JDK 7) :

import android.util.Base64 

public byte[] encode(byte[] bytearrayToEncode){ 
    return Base64.encode(bytearrayToEncode, Base64.NO_WRAP|Base64.URL_SAFE); 
} 

디코딩 (서버 : 리눅스, jdk 8) :

import java.util.Base64 

public byte[] decode(byte[] bytearrayToEncode){ 
    return Base64.getUrlDecoder().decode(bytearrayToDecode); 
} 

문자열은 모두 동일한 문자 세트 (utf-8)로 인코딩 해제됩니다! 인코딩/디코딩 : Base64로

암호화 : 좀 더 자세한 정보가 필요하면 AES

, 그냥 물어,하지만 난 모든이 켜지지 정보를 제공 생각합니다.

편집 : 당신은 서버에 Base64로 문자열을 보낼 JSONObjects를 사용하고 있어야합니다

public String bytearrayToString(byte[] bytearray){ 
    String str = null; 
    try { 
     str = new String(bytearray, "UTF-8"); 
    } catch (UnsupportedEncodingException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    return str; 
} 

public byte[] stringToBytearray(String str){ 
    byte[] bytearray = null; 
    try { 
     bytearray = str.getBytes("UTF-8"); 
    } catch (UnsupportedEncodingException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    return bytearray; 
} 
+0

0x5b가 [이며, 내가 말한대로 문자열 형식] [문자열 ... 문자열입니다. 그러나 String이 너무 길면 모든 인코딩/디코딩은 Device에서는 작동하지만 Server에서는 작동하지 않는 이유는 무엇입니까? (나는 두 개의 긴 문자열을 비교해도 같음) – user3469811

+0

길이가 너무 길면 서버가 쿼리 매개 변수를 자르고 있습니까? 받은 Base-64 메시지를 에코하여 정확히 일치하는지 확인하십시오. 잘린 문자열은 더 이상 유효한 Base-64로 암호화 된 메시지가 아니기 때문입니다. – D3V

+0

나는 encode의 두 번째 호출이 적용되지 않는다는 것을 알았다. 지금까지 모든 제안에 감사드립니다! 나는 왜 그것이 나던 지 알아 내려고 노력할 것이다. – user3469811

답변

9

. 그렇다면 JSONObject는 잘못된 Base64 문자 인 "\"이스케이프 문자를 문자열에 추가합니다. 당신이 할 필요가 획득 한 문자열을 사용하기 전에 서버 측에

String rectifiedString = Base64String.replace("\\",""); 

입니다.

import javax.xml.bind.DatatypeConverter; 

String result = DatatypeConverter.printBase64Binary(bytearrayToDecode);

byte[] result = DatatypeConverter.parseBase64Binary(str); 

대신 서버 측 용도에서도

선택

.

작업이 완료 될뿐만 아니라 인코딩/디코딩 (as benchmarked here)에서 훨씬 빠릅니다.

+1

날 위해 printBase64Binary처럼 당신을 위해 백 슬래시를 제거합니다. 통찰력에 감사드립니다. OP와 같은 문제가있었습니다. – cloudsurfin

1

인코딩 된 문자열에 공백이 있으면 base64에서 잘못된 문자입니다. 이 코드를 제거하면 링크 된 변환기에서 여전히 동일한 이미지/데이터가 생성되므로 코드에 의해 디코딩 될 수 있습니다.

UPDATE : 일부 디코더 (당신이 연결된 하나 또는 Java에서 Base64.getMimeDecoder()와 같은) 잘못된 문자를 무시, 다른 사람 (Base64.getDecoder 등은())을 허용하지 않습니다. 인코딩에 대한

0

사용 :

Base64.getEncoder().encodeToString(yourString.getBytes("UTF-8")); 

및 디코딩 :

byte[] decodedBytes = Base64.getDecoder().decode(yourString); 
String stringDecode = new String(decodedBytes, "UTF-8");