Base64 Hex 변환 원리와 홀수 길이 오류 이유

Base64 문자열과 16진수(Hex) 문자열은 전혀 다른 글자처럼 보이지만, 사실은 같은 바이너리 데이터를 표기하는 방식이 다를 뿐입니다. 해시값이나 인코딩된 데이터를 다른 형식으로 옮겨 적어야 하는 사람이라면 한 번쯤 이 변환이 필요합니다. 이 글은 변환 과정에서 내부적으로 어떤 계산이 일어나는지, 그리고 자주 막히는 지점을 사실 위주로 정리합니다.
요약 ① Base64와 Hex는 같은 바이트 데이터를 다른 문자 규칙으로 표기한 것뿐이며, 정보량과 실제 값은 동일합니다. ② Hex 문자열은 1바이트를 항상 두 자리로 적기 때문에, 길이가 홀수이면 마지막 글자가 바이트를 이루지 못해 오류가 납니다. ③ 바이트 공백·대소문자 옵션이나 붙여넣은 문자열의 공백·구분기호는 표기 방식만 바꿀 뿐, 변환되는 실제 바이트 값에는 영향을 주지 않습니다.
이런 상황에서 막힙니다
예를 들어 어떤 파일이나 문자열의 SHA-256 해시값을 계산했을 때, 커맨드 라인 도구나 일부 라이브러리는 결과를 16진수 문자열로 출력합니다. 반면 다른 API 응답이나 라이브러리는 같은 해시값을 Base64 문자열로 돌려줍니다.
두 문자열은 전혀 다르게 생겼기 때문에, 처음 보면 계산이 잘못됐거나 서로 다른 값처럼 보입니다. 하지만 실제로는 같은 바이트 배열을 두 가지 다른 문자 규칙으로 적은 것뿐입니다.
이럴 때 한쪽 값을 다른 표기법으로 바꿔서 나란히 놓고 비교해야, 두 값이 실제로 같은 데이터를 가리키는지 눈으로 확인할 수 있습니다.
도구 없이 손으로 계산하는 방법
Base64와 Hex 사이의 변환은 특별한 도구 없이도 직접 계산할 수 있습니다. Hex 문자열 "48656c6c6f"를 Base64로 바꾸는 과정을 예로 들겠습니다. (이 값은 문자 "Hello"를 아스키 코드로 표기한 것입니다.)
Hex를 Base64로 바꾸는 계산 순서
1단계 — Hex를 두 자리씩 끊어 바이트로 만듭니다. 48, 65, 6c, 6c, 6f — 다섯 개의 바이트입니다.
2단계 — 각 바이트를 10진수와 8비트 이진수로 바꿉니다.
| Hex | 10진수 | 8비트 이진수 |
|---|---|---|
| 48 | 72 | 01001000 |
| 65 | 101 | 01100101 |
| 6c | 108 | 01101100 |
| 6c | 108 | 01101100 |
| 6f | 111 | 01101111 |
3단계 — 이진수를 순서대로 이어 붙인 뒤, 앞에서부터 6비트씩 끊습니다. 마지막 그룹이 6비트에 못 미치면 뒤에 0을 채웁니다.
010010 000110 010101 101100 011011 000110 111100
4단계 — 각 6비트 값(0~63)을 Base64 표에서 찾습니다. Base64 표는 AZ가 025, az가 2651, 09가 5261, +가 62, /가 63입니다.
18→S, 6→G, 21→V, 44→s, 27→b, 6→G, 60→8
5단계 — 문자 수를 4의 배수로 맞추기 위해 '='를 채웁니다. 원래 바이트 수(5개)가 3의 배수보다 2개 남으므로, 부족한 자리만큼 '='를 1개 붙입니다.
결과: SGVsbG8=
Base64를 Hex로 바꾸는 계산 순서
Base64를 Hex로 바꾸는 계산은 이 과정을 거꾸로 밟으면 됩니다. Base64 문자마다 표에서 인덱스(0~63)를 찾아 6비트로 적고, 이어 붙인 뒤 앞에서부터 8비트씩 끊어 바이트로 만들고, 각 바이트를 16진수 두 자리로 적으면 됩니다.
저희 도구로 확인하기.
입력과 동시에 브라우저에서 바로 변환되며, 서버로 전송되지 않습니다.

헷갈리기 쉬운 부분
실제로 도구를 쓰다 보면 몇 가지 지점에서 헷갈립니다. 아래 표로 정리했습니다.
| 상황 | 실제로 일어나는 일 |
|---|---|
| Hex 문자열 길이가 홀수 | 마지막 한 글자가 바이트 하나를 이루지 못해 오류 발생 |
| Hex에 공백·하이픈 등이 섞여 있음 | 0-9, A-F(a-f) 이외 문자는 자동으로 제거되고 나머지로 변환 |
| Base64에 공백·줄바꿈이 섞여 있음 | 공백만 자동으로 제거된 뒤 디코딩 |
| Base64에 공백이 아닌 잘못된 문자가 섞여 있음 | 제거되지 않아 디코딩 오류로 이어질 수 있음 |
| "바이트 공백"·"대문자" 옵션 켜기/끄기 | 실제 바이트 값은 그대로, Hex의 표기 형식만 변경 |
Hex 입력창에 홀수 개의 16진수 문자를 넣으면 "16진수 문자열의 길이는 짝수여야 합니다."라는 오류 문구가 표시됩니다. 2자리가 1바이트를 이루는 규칙 때문에, 마지막 한 글자만 남으면 바이트 하나를 완성할 수 없어서입니다.
Base64 쪽과 Hex 쪽은 무시하는 문자 범위가 다릅니다. Hex는 16진수가 아닌 모든 문자를 지우지만, Base64는 공백과 줄바꿈만 지웁니다. 이 차이를 모르고 Base64에 구분기호를 섞어 붙여넣으면 디코딩이 실패할 수 있습니다.
정리
- Base64와 Hex는 같은 바이너리 데이터를 나타내는 서로 다른 문자 표기법입니다.
- Hex는 1바이트를 두 자리로 표기하므로 문자열 길이가 항상 짝수여야 합니다.
- 변환은 6비트(Base64) 또는 8비트(바이트) 단위로 비트를 재배열하는 계산이며, 손으로도 재현할 수 있습니다.
- 바이트 공백·대문자 옵션은 표기 형식만 바꿀 뿐 실제 데이터 값에는 영향을 주지 않습니다.
- 붙여넣은 문자열에 섞인 불필요한 문자는(Hex는 비16진수 전체, Base64는 공백만) 자동으로 정리된 뒤 변환됩니다.
입력과 동시에 브라우저에서 바로 변환되며, 서버로 전송되지 않습니다.
자주 묻는 질문
Hex 문자열 길이가 홀수면 왜 오류가 나나요?
Hex 표기에서 한 바이트는 항상 두 자리로 적습니다(00~ff). 문자열 길이가 홀수이면 마지막 한 글자가 어느 바이트에도 속하지 못하고 남기 때문에, "16진수 문자열의 길이는 짝수여야 합니다."라는 오류가 표시됩니다.
Hex 값에 공백이나 구분기호가 섞여 있어도 붙여넣을 수 있나요?
네, 붙여넣은 Hex 문자열에서 0-9, A-F(a-f)가 아닌 문자는 자동으로 무시되고 나머지 문자만으로 변환이 이루어집니다. 다른 도구에서 공백이나 콜론으로 구분된 Hex 값을 복사해 그대로 붙여넣어도 됩니다.
"바이트 공백"이나 "대문자로 표시" 옵션을 켜면 변환 결과 값이 달라지나요?
아니요. 두 옵션은 Hex 문자열을 화면에 어떻게 표시할지만 바꿉니다. 바이트마다 공백을 넣을지, a-f를 소문자로 둘지 대문자로 바꿀지의 표기 차이일 뿐, 디코딩되는 실제 바이트 값은 동일합니다.
Base64 문자열 끝에 붙는 '=' 기호는 지워도 되나요?
'=' 기호는 원래 데이터가 3바이트 단위로 딱 나뉘지 않을 때 남는 자리를 채우는 패딩 문자입니다. 이 기호를 지우면 디코더가 바이트 경계를 정확히 계산하지 못해 오류가 나거나 잘못된 값으로 디코딩될 수 있습니다.
