Post

자바 Base64 인코딩 및 디코딩

1. Base64용 자바 8

Java 8은 마침내 java.util.Base64 유틸리티 클래스를 통해 표준 API에 Base64 기능을 추가 했다.

1) 자바 8 기본 Base64

기본 인코더는 작업을 단순하게 유지하고 입력을 줄 분리 없이 있는 그대로 인코딩한다.

인코더는 입력을 A-Za-z0-9+/ 문자 집합의 문자 집합에 매핑한다.

먼저 간단한 String을 인코딩해본다.

1
2
String originalInput = "test input";
String encodedString = Base64.getEncoder().encodeToString(originalInput.getBytes());

간단한 getEncoder() 유틸리티 메소드를 통해 전체 Encoder API를 검색하는 방법에 유의한다.

이제 해당 문자열을 원래 형식으로 다시 디코딩한다.

1
2
byte[] decodedBytes = Base64.getDecoder().decode(encodedString);
String decodedString = new String(decodedBytes);

2) 패딩 없는 Java 8 Base64 인코딩

Base64 인코딩에서 출력 인코딩된 문자열의 길이는 3의 배수여야 한다. 인코더는 이 요구 사항을 충족하기 위해 필요에 따라 출력 끝에 하나 또는 두 개의 패딩 문자(=)를 추가한다.

디코딩 시 디코더는 이러한 추가 패딩 문자를 버린다.

때로는 출력 패딩을 건너뛸 필요가 있다. 예를 들어 결과 문자열은 다시 디코딩되지 않는다. 따라서 패딩 없이 인코딩 하도록 선택할 수 있다.

1
String encodedString = Base64.getEncoder().withoutPadding().encodeToString(originalInput.getBytes());

3) 자바 8 URL 인코딩

URL 인코딩은 기본 인코더와 매우 유사하다. 또한 URL 및 파일 이름 Safe Base64 알파벳을 사용한다. 또한 줄 구분을 추가하지 않는다.

1
2
String originalUrl = "https://www.google.co.nz/?gfe_rd=cr&ei=dzbFV&gws_rd=ssl#q=java";
String encodedUrl = Base64.getUrlEncoder().encodeToString(originalURL.getBytes());

디코딩은 거의 동일한 방식으로 발생한다. getUrlDecoder() 유틸리티 메소드는 java.util.Base64.Decoder를 리턴한다 . 따라서 URL을 디코딩하는데 사용한다.

1
2
byte[] decodedBytes = Base64.getUrlDecoder().decode(encodedUrl);
String decodedUrl = new String(decodedBytes);

4) 자바 8 MIME 인코딩

인코딩할 몇 가지 기본 MIME 입력을 생성하여 시작한다.

1
2
3
4
5
6
7
private static StringBuilder getMimeBuffer() {
    StringBuilder buffer = new StringBuilder();
    for (int count = 0; count < 10; ++count) {
        buffer.append(UUID.randomUUID().toString());
    }
    return buffer;
}

MIME 인코더는 기본 알파벳을 사용하여 Base64로 인코딩된 출력을 생성한다. 그러나 형식은 MIME 친화적이다.

출력의 각 줄은 76자를 넘지 않는다. 또한 캐리지 리턴과 줄 바꿈(\r\n)으로 끝난다.

1
2
3
StringBuilder buffer = getMimeBuffer();
byte[] encodedAsBytes = buffer.toString().getBytes();
String encodedMime = Base64.getMimeEncoder().encodeToString(encodedAsBytes);

디코딩 프로세스에서 java.util.Base64.Decoder를 반환하는 getMimeDecoder() 메서드를 사용할 수 있다.

1
2
byte[] decodedBytes = Base64.getMimeDecoder().decode(encodedMime);
String decodedMime = new String(decodedBytes);

2. Apache Commons Code를 사용한 인코딩/디코딩

먼저 pom.xml 에서 commons-codec 종속성 을 정의해야 한다.

1
2
3
4
5
<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.15</version>
</dependency>

주요 API는 org.apache.commons.codec.binary.Base64 클래스이다. 다양한 생성자로 초기화할 수 있다.

  • Base64(boolean urlSafe)는 URL 안전 모드(켜기 또는 끄기)를 제어하여 Base64 API를 생성한다.

  • Base64(int lineLength)는 URL 안전하지 않은 모드에서 Base64 API를 생성하고 줄의 길이를 제어한다(기본값은 76).

  • Base64(int lineLength, byte[] lineSeparator)는 기본적으로 CRLF(\r\n)인 추가 줄 구분자를 허용하여 Base64 API를 만든다.

Base64 API가 생성되면 인코딩과 디코딩이 모두 매우 간단하다.

1
2
3
String originalInput = "test input";
Base64 base64 = new Base64();
String encodedString = new String(base64.encode(originalInput.getBytes()));

또한 Base64 클래스의 decode() 메서드는 디코딩된 문자열을 반환한다.

1
String decodedString = new String(base64.decode(encodedString.getBytes()));

또 다른 옵션은 인스턴스를 생성하는 대신 Base64의 정적 API를 사용하는 것이다.

1
2
3
String originalInput = "test input";
String encodedString = new String(Base64.encodeBase64(originalInput.getBytes()));
String decodedString = new String(Base64.decodeBase64(encodedString.getBytes()));

3. 문자열을 바이트 배열로 변환

때로는 String을 byte[]로 변환해야 한다. 가장 간단한 방법은 String getBytes() 메서드를 사용하는 것이다.

1
2
3
4
String originalInput = "test input";
byte[] result = originalInput.getBytes();

assertEquals(originalInput.length(), result.length);

기본 인코딩에 의존하지 않고 인코딩도 제공할 수 있다. 결과적으로 시스템에 따라 다르다.

1
2
3
4
String originalInput = "test input";
byte[] result = originalInput.getBytes(StandardCharsets.UTF_16);

assertTrue(originalInput.length() < result.length);

문자열이 Base64로 인코딩된 경우 Base64 디코더를 사용할 수 있다.

1
2
3
4
String originalInput = "dGVzdCBpbnB1dA==";
byte[] result = Base64.getDecoder().decode(originalInput);

assertEquals("test input", new String(result));

DatatypeConverter parseBase64Binary() 메서드를 사용할 수도 있다.

1
2
3
4
String originalInput = "dGVzdCBpbnB1dA==";
byte[] result = DatatypeConverter.parseBase64Binary(originalInput);

assertEquals("test input", new String(result));

마지막으로 DatatypeConverter.parseHexBinary 메서드를 사용하여 16진수 문자열을 byte[]로 변환할 수 있다.

1
2
3
4
String originalInput = "7465737420696E707574";
byte[] result = DatatypeConverter.parseHexBinary(originalInput);

assertEquals("test input", new String(result));

[출처 및 참고]

This post is licensed under CC BY 4.0 by the author.