일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- transaction
- Python
- HTTP
- iamport
- 노마드코드
- 재태크
- 레일즈 캐시
- Cache
- rails cache
- redis
- 노마드코더
- restful
- Race Condition
- memcached
- 아임포트
- 투자
- redis transaction
- 사업
- 레일즈
- django
- CU
- 북클럽
- API
- 주식
- 노개북
- Rails
- 경제
- trouble shooting
- Watcha pedia
- Today
- Total
Stay hungry, Stay foolish
encoding, UTF-8, base-64 가 뭐고 왜 쓰는 것일까? 본문
개발을 하다가 한글이 이렇게 깨지는 것을 본적이 있으신가요?
원인은 encoding 설정이 잘못되어있기 때문입니다.
그러면 encoding이 무엇인지 살펴보겠습니다.
encoding 이란
컴퓨터는 기본적으로 정보를 0, 1 Binary로 정보를 읽고 쓰고 하는데 우리 휴먼들은 01011101110000111 이걸 가지고 읽어보라고 하면.. 대략 난감할텐데요.
그렇기 때문에 숫자, 문자를 아래와 같이 binary로 치환된 문자열 set 을 가지고 컴퓨터는 정보를 읽고 쓰는거라고 할 수 있습니다.
이렇게 문자를 컴퓨터가 알아볼 수 있는 binary 로 바꿔주는 것을 문자 encoding 이라고 합니다
그렇다면 문자가 깨지는 이유는 뭘까?
위키에서 문자 인코딩을 찾아보면 종류가 엄청 많군요...
초창기에는 미국에서 만든 ASCII 문자열 set이 표준이었는데 이 문자열 set으로는 한글이나 여타 외국어들을 encoding 할 수 없었는데요
그렇기 때문에 각 언어별 문자셋 춘추전국시대가 생긴것입니다.
하지만 이 춘추전국시대를 통일할 표준 문자셋이 필요했고 이를 위해 Unicode 가 나오게 된것입니다.
UTF-8은 뭘까요?
Unicode는 위의 이미지같은 문자셋이고, 이 Unicode를 컴퓨터에 Binary로 어떻게 치환해서 메모리를 할당하는지 encoding하는 방법중 하나가 UTF-8입니다.
한글을 사용할 수 있는 표준 encoding에는 UCS-2, UCS-4, UTF-32, UTF-16, UTF-8 등 다양한 방식이 있는데 그 중 UTF-8이 다른 encoding 방식들 보다 평균적으로 적은 메모리를 사용하고 호환문제도 가장 덜한 UTF-8이 전세계적으로 가장 많이 사용되는것입니다.
Base64
Base64 라는 것도 들어보셨나요? base64 란 Binary Data를 역으로 ASCII 영역의 문자열로 인코딩하는 방식을 말합니다.
base 64 라는걸 글자 그대로 보면 64진법 이라는 뜻을 가지는데 이는 2의 6제곱 64개의 ASCII 문자로 표현함을 뜻합니다. 이 64개의 character set은 A-Z a-z 0-9 의 62개 character 와 나머지 2개의 기호로 이루어져 있으며 이 2개의 기호에 따라 종류별 차이가 나뉩니다.
이 Base64에서 알아야 할것은 인코딩된 텍스트에 ~~= 와 같이 "=" 기호로 끝나게 되는 문자열들을 볼 수 있는데 이는 부족한 bit수를 =로 채워 나타내는 padding 문자입니다.
그렇다면 왜 bit 수가 부족한 것일까요?
변환과정을 살펴보자면
이 64개의 character set으로 모든 문자열을 표현하자면 2의 6제곱 즉 6bit 가 필요합니다. 하지만 일반적으로 ASCII 문자는 8bit로 구성되어 있습니다. 그렇기 때문에 Base64 인코딩을 위해 binary data를 6bit 씩 묶고자 6과 8의 최소공배수인 24 bit 씩 끊어 묶도록 하기 때문에 변환과정에서 공백이 발생하게 되는것입니다. 사실 여기까지 봐도 무슨 말인가 싶죠.
위키에 나와있는 예로 한번 볼까요?
Man이라는 단어를 base64 인코딩 하면 아래와 같습니다.
Text content | M | a | n | |||||||||||||||||||||
ASCII | 77 | 97 | 110 | |||||||||||||||||||||
Bit pattern | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | 1 | 0 |
Index | 19 | 22 | 5 | 46 | ||||||||||||||||||||
Base64-Encoded | T | W | F | u |
Man의 ASCII binary 값이 010011 / 010110 / 000101 / 101110 과 같이 6bit 씩 쪼개어져서 Base64로 인코딩 되는 과정을 거치죠
공백이 없습니다!
하지만 Ma 만 본다면요?
8bit x 2 로 16 bit이고 6bit씩 자르면 4bit 가 남게됩니다.
Text content | M | a | ||||||||||||||||||||||
ASCII | 77 | 97 | ||||||||||||||||||||||
Bit pattern | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | ||||||
Index | 19 | 22 | 4 | padding | ||||||||||||||||||||
Base64-Encoded | T | W | E | = |
이렇게 4bit 가 벙 떠버렸네요 이렇게 남는 4bit의 자리는 0으로 채우게 되고 index 4에 해당하는 문자열 E 로 인코딩 되는것이죠
그렇다면 마지막에 24bit 중 남은 6bit 를 위해 padding 문자인 "=" 로 채워주게 되는겁니다.
근데 이러한 변환과정 때문에 base64로 인코딩한 파일은 원본보다 사이즈가 커지게 됩니다.
그렇다면 왜 굳이 base64를 사용 하는것일까요
안전성 때문이라고 말씀드리고 싶습니다.
ASCII 로 인코딩하여 전송한다면 ASCII는 7bits encoding으로 나머지 1bit를 처리하는 방식이 시스템별로 상이하며 일부 제어문자도 시스템별로 다른 코드값을 갖게 됩니다. 하지만 Base64의 경우에는 ASCII 중 제어문자와 일부 특수문자를 제외한 53개의 안전한 출력 문자만 이용하므로 데이터 전달과정에 있어 누락없이 데이터를 안전하게 전송할 수 있게되는것이죠.
ref.
'CS 지식' 카테고리의 다른 글
브라우저 작동원리와 SSR / CSR (0) | 2022.06.13 |
---|