몇일 전에 [입 개발] base62와 진법 연산 라는 글을 적었습니다. 이런 내용을 얘기하면 꼭 빠지지 않고 좋은 질문이 하나 꼭 나옵니다.(나오기를 바랍니다.)
“왜 base64가 있는데 base62 같은걸 써야하죠?” 넵 그렇습니다. 다행히도, 이 내용을 제 주변에 설명했을 때도, 들었던 질문이고, 해당 글을 적었을 때도 받은 질문입니다.(좋은 질문해주신 질문자들에게 감사드립니다.)
먼저 간단하게 설명을 시작하기 전에, 10진수는 영어로 decimal 또는 base 10, 8진수는 octet digits 또는 base 8, 그럼 16진수는 넵 hexdecmial 또는 base 16 이 됩니다. 그럼 당연히 base62는 62진법, base64는 64진법이겠죠.
이 얘기를 하면, 위의 질문이 더 좋아집니다. 64진법으로 표현하는게, 62진법으로 표현하는 것 보다, 진법이 크니, 변화된 정보량이 더 작아지지 않는가? 라는 생각을 하게 하니깐요.
그런데 정답부터 말하자면, base64의 정보량이 더 줄어드는것이 맞습니다.(엥 작성자 양반 도대체 무슨 소리를 하는것이오…) 그런데, 이것을 항상 쓸 수 있는가? 라고 물어보면… 그렇지는 않기 때문입니다.(작성자 양반 이것은 또 무슨소리오!!!)
일단 binary로 표현하는 것은 일종의 256진법 표기입니다. base62, 64에 비해서 한 바이트에 많은 정보가 함축되지요. 그런데, 이제 다음과 같은 질문이 추가로 나와야 할듯 합니다. base64는 왜 나왔을까요? 아무데나 다 쓸 수 있나요? 아래는 base64에서 사용하기 위한 인코딩 표입니다. base62와 비교하면, 사실 +,/,= 해서 3개를 더 쓰고 있습니다.(마지막에 =는 사실 padding 입니다. 값이 없다라는 것을 알려주기 위해서이죠.)
자, 이제 다시 한번 질문드립니다. 위의 base64 문자표에 있는 값으로 구성을 하면, 웹 url 형태의 query string으로 넘겼을 때 제대로 처리가 될까요? 자자 열심히 머리를 굴려봅시다.(이 질문을 하는 이유는… 심지어 이 글을 쓰는 이유는 여기서 뭔가 제대로 처리가 되지 않기 때문이겠죠?
https://charsyam.wordpress.com/abc?q===query=abcd+/=
위의 query string ㅔ서 q== 이 key 이고 query=abcd+/= 가 value라고 하면 뭔가 이상합니다. 하지만, key와 value 가 모두 base64로 인코딩이 된다면, 가능한 일입니다. 그럼 이제 패드는 안쓴다고 해봅시다. 그래도 다음과 같은 형태는 가능합니다.
https://charsyam.wordpress.com/abc?q+/+=query+/
그래서 url safe base64 라는 형태를 찾아보면 위의 표에서 ‘+’, ‘/’ 를 각각 ‘-‘,’_’ 등으로 바꾸고, ‘=’도 ‘.’ 이나 다른 문자로 바꾸는 경우가 있습니다. 즉 base64의 테이블표를 변경해야 하는 이슈가 생기는 것입니다.
실제로 base64는 이메일에서 안전하게 메일을 보내기 위한 인코딩 방법으로 출발했습니다. (rfc1341 를 참고하세요.)예전에는 ascii 만이 세상의 표준이므로 대부분의 서비스들이 7bit 까지만 인식하고 8bit로 된 데이터는 뭔가 처리하는데 에러가 있는 시대였습니다. 그래서 우리의 EUC-KR로 표현되던 한글이나 2byte 언어 국가 CJK 같은 경우는 메일로 첨부파일도 못보내고, 더 심한건, 그냥 한글로는 메일을 못보낸다는 것입니다.(EUC-KR 등에서는 한글 표현을 위해서 2byte를 사용하는데, 확장 표시를 위해서 두 byte의 첫 bit를 1로 셋팅했습니다.) 그래서 여기서 좀 안전한 방법을 찾자가 quoted-printed 와 base64 가 나오게 되었습니다.(quoted-printed는 url-encode 와 유사하게 128보다 큰 문자는 %AB 이런식으로 3글자로 표시하는 방식입니다.)
위와 같은 이유로 base64가 나오게 된 것입니다. 경우에 따라서 테이블을 변경해서 쓰거나 해야 안전해 지는 것이죠. 그런데… base64에서 사용하는 문자들을 또 특정한 시스템에서 쓸 수 없다면 어떻게 될까요? 8bit 표현을 6bit 로 줄인것 처럼, 64로 표시할 수 있는 데이터를 다시 더 줄여야 할 필요가 생길 수 있습니다. base62 또한 그런 상황에서 필요가 되어서 만들어 진 것이죠. 예를 들어 web에서 사용하는데 벌써 ‘-‘, ‘_’ 는 예약 문자등으로 쓰여서 쓸 수 없거나 하는…
그래서 base62, base36, base26, base10 등 얼마든지 만들어 나갈 수 있습니다. encoding, decoding 이라는 것은, 이러한 상황에서의 문제를 풀기 위해서고, 이런 문제는 얼마든지 다시 발생할 수 있으니까요. 설명이 되었으면 좋겠습니다.