Base64 끝의 =는 원문에 들어 있던 문자가 아니라 패딩입니다. Base64는 원본 3바이트를 출력 4문자로 표현합니다. 마지막 묶음에 1바이트만 남으면 ==, 2바이트가 남으면 =를 붙여 패딩 포함 형식의 묶음을 완성합니다.
패딩이 1개 또는 2개 붙는 원리
Base64 데이터 문자 하나는 6비트를 표현합니다. 3바이트는 24비트이므로 4문자에 정확히 들어갑니다. 마지막에 1바이트가 남으면 데이터 2문자와 ==를 쓰고, 2바이트가 남으면 데이터 3문자와 =를 씁니다. 패딩은 출력 묶음을 채우는 표시이며 디코딩 결과에 바이트를 추가하지 않습니다.
문자 수가 아니라 바이트 수를 봐야 합니다
f, fo, foo는 각각 UTF-8에서 1·2·3바이트입니다. 한글이나 이모지는 화면에 보이는 한 문자도 여러 바이트일 수 있습니다. 예를 들어 😀는 4바이트여서 8J+YgA==로 변환됩니다. 눈에 보이는 글자 수만으로 =의 개수를 정할 수는 없습니다.
패딩 없는 Base64에 =를 다시 붙이는 방법
패딩 생략을 허용하는 형식에서는 공백을 제거한 데이터 문자열의 길이를 4로 나눈 나머지를 확인합니다. 나머지가 2면 ==, 3이면 =, 0이면 추가하지 않습니다. 나머지가 1이면 패딩을 붙여도 정상적인 Base64가 될 수 없으므로 문자열이 손상되거나 잘렸는지 확인해야 합니다.
Zg는 되고 Zg=는 실패하는 이유
Decodex는 패딩이 완전히 생략된 Zg를 받아 Zg==로 복원하여 f로 변환합니다. 반면 Zg=는 패딩이 일부만 붙은 상태이고 전체 길이도 올바르지 않아 오류로 처리합니다. A=AA처럼 중간에 패딩이 있거나 Zg===처럼 너무 많은 패딩이 있는 입력도 실패합니다. 무작정 =를 더하거나 삭제하지 마세요.
언제 =를 유지해야 하나요?
전달할 프로토콜이 패딩 생략을 명시적으로 허용하거나 요구하지 않는다면 인코더가 만든 패딩을 유지하는 편이 맞습니다. 일반 Base64와 특정 Base64URL 기반 서비스는 요구사항이 다를 수 있습니다. API에서 패딩 오류가 나면 먼저 문서와 복사 과정의 문자 손실을 확인하세요.
예제로 직접 변환하기
| 텍스트 | UTF-8 bytes | Base64 | 패딩 |
|---|---|---|---|
f | 1 | Zg== | == |
fo | 2 | Zm8= | = |
foo | 3 | Zm9v | — |
자주 묻는 질문
끝에 =가 없어도 정상인가요?
네. 원본 바이트 수가 3의 배수라면 패딩 포함 Base64도 =가 필요 없습니다. 일부 프로토콜은 마지막 묶음의 패딩을 의도적으로 생략하기도 합니다.
끝의 =는 원래 비밀번호에 포함된 문자인가요?
아니요. 패딩은 마지막 인코딩 묶음의 상태를 나타냅니다. 원문에 =가 있다면 그 바이트 자체가 다른 입력과 똑같이 인코딩됩니다.