문제
Java에서 Base64 디코딩을 시도하는 과정에서 java.lang.IllegalArgumentException: Illegal base64 character a
오류가 발생했다. 이 오류는 Base64 문자열에 유효하지 않은 문자가 포함되어 있음을 나타내는 건데, charater a
라는 에러메시지때문에 괜히 헤맸기 때문에 이 글을 남긴다.
Base64 인코딩은 일반적으로 A-Z, a-z, 0-9, +, / 문자와, 끝에 '=' 패딩 문자를 사용한다. 범위 밖의 문자가 포함되어 있으면 유효하지 않은 Base64 문자열이 되어 예외가 발생하는데, character a
라는 메시지때문에 원인을 찾기가 쉽지 않았다.
원인
일단 결론적으로 원인은 base64 문자열을 복사하는 과정에서 의도치 않은 줄바꿈 문자가 발생했기 때문이었다.
동일한 에러 상황을 재현해보자.
package com.tistory.shanepark.string.encoding;
import java.util.Base64;
public class Base64Error {
public static void main(String[] args) {
String base64 = "SGVsbG8sIFdvcmxkIQ\n==";
byte[] decodedBytes = Base64.getDecoder().decode(base64.getBytes());
System.out.println(new String(decodedBytes));
}
}
위의 코드를 실행하면 정확히 같은 내용의 에러가 발생한다.
Exception in thread "main" java.lang.IllegalArgumentException: Illegal base64 character a
해결
공백문자를 제거 하는 코드를 추가해준다. \\s+
는 하나 이상의 연속된 공백 문자를 의미한다.
해당 코드로 스페이스(' '), 탭('\t'), 줄바꿈('\n'), 캐리지 리턴('\r'), 폼 피드('\f') 등의 포함 문제를 모두 해결할 수 있다.
package com.tistory.shanepark.string.encoding;
import java.util.Base64;
public class Base64Error {
public static void main(String[] args) {
String base64 = "SGVsbG8sIFdvcmxkIQ\n==";
base64 = base64.replaceAll("\\s+", ""); // 모든 공백 문자 제거
byte[] decodedBytes = Base64.getDecoder().decode(base64.getBytes());
System.out.println(new String(decodedBytes));
}
}
실행 결과 문제 없이 디코딩 해낸다.
에러메시지 분석
왜 하필 base64 character a
라는 에러메시지였을까? 에러가 발생한 Base64 라이브러리를 살펴보자.
에러가 발생한 부분이다. 'a' 라고 보여진건 실제 알파벳 a
가 아닌16진수였다.
16진수 a는 십진수로 10
을 의미한다. 그러면 아스키코드 테이블에서 10을 찾아보자.
아스키코드에서 10은 LF(Line Feed)
를 의미한다. 드디어 에러메시지의 미스테리가 풀렸다.
그렇다면 Base64 라이브러리의 에러 메시지에서는 굳이 저걸 왜 16진수로 변환해서 헷갈리게 만들었을까?
이번에는 반대로 생각해보자. 만약 에러메시지에 a
가 아닌 \n
이 직접 출력되었다면 문제를 알아내기가 더 쉬웠을까? 줄바꿈 문자가 그대로 출력되면서 결국 아무 문자도 볼 수 없었을것이다. LF 외의 다른 많은 아스키 비표시 문자도 마찬가지다.
이제 실제 문자가 아닌 아스키 번호를 보여주는 편이 낫다는건 납득이 된다. 다만 0xa
처럼 16진수라는걸 명확하게 표시해줬으면 좀 낫지 않았을까 하는 아쉬움이 남는다.
'Development > Daily Error' 카테고리의 다른 글
Apache Commons net 한글 파일명 문제 해결 (0) | 2024.01.10 |
---|---|
[Nginx] 413 Request Entity Too Large 문제 해결 (0) | 2023.12.19 |
골치아픈 공공데이터포털 serviceKey 인코딩 문제 (0) | 2023.05.28 |
IRODS ) Quota 제한 넘기지 못하도록 강제하기 (0) | 2023.04.11 |
Spring Boot 3 에서 MYSQL 의존성 못찾는 경우 (0) | 2023.04.02 |