UTF-8은 유니코드(Unicode)를 저장하거나 전송하기 위한 방식이고,
ASCII 코드도 유니코드의 일부이기 때문에 UTF-8로 자동 인코딩/디코딩이 가능하다.
유니코드(Unicode)는 "모든 문자"에 대해 고유한 번호(U+xxxx)를 부여한 문자 집합(표)이다.
예) 'A' → U+0041, '가' → U+AC00, '😃' → U+1F603
ASCII는 유니코드의 일부로, U+0000 ~ U+007F (0~127) 범위에 해당한다.
'A' = 0x41, '1' = 0x31, '@' = 0x40 등UTF-8은 유니코드의 번호(U+xxxx)를 1~4바이트의 이진수(바이트)로 인코딩하는 방법입니다.
✔️ ASCII 문자인 'A'는 0x41
✔️ 한글 '가'는 0xEA 0xB0 0x80
✔️ 이모지 '😃'는 0xF0 0x9F 0x98 0x83로 인코딩된다.
| 문자 | 유니코드(U+xxxx) | UTF-8 인코딩 (16진수) | 바이트 수 |
|---|---|---|---|
| A | U+0041 | 41 | 1바이트 |
| 가 | U+AC00 | EA B0 80 | 3바이트 |
| 😃 | U+1F603 | F0 9F 98 83 | 4바이트 |
UTF-8은 문자의 유니코드 값을 보고 아래처럼 바이트 수를 정합니다:
| 유니코드 범위 | 바이트 수 | 첫 바이트 시작 비트 | 실제 데이터 비트 수 계산 | 총 데이터 비트 |
|---|---|---|---|---|
| 0x0000 ~ 0x007F | 1바이트 | 0xxxxxxx (ASCII) | 7 | 7 |
| 0x0080 ~ 0x07FF | 2바이트 | 110xxxxx 10xxxxxx | 5 + 6 | 11 |
| 0x0800 ~ 0xFFFF | 3바이트 | 1110xxxx 10xxxxxx 10xxxxxx | 4 + 6 + 6 | 16 |
| 0x10000 ~ 0x10FFFF | 4바이트 | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx | 3 + 6 + 6 + 6 | 21 |
최대 6바이트까지 표현 가능하지만 다른 인코딩과 호환을 위해 4바이트까지만 사용한다.
첫 바이트의 1과0으로 채워진 bit는 시그니쳐로 생각하면 됩니다. 첫 바이트의 bit가 111000101 이렇게 되어 있으면 “3바이트를 사용하겠다!”라는 내용을 내포하고 있습니다. 그 뒤에 바이트 앞에 10으로 시작되면 중간에 존재하는 바이트라고 보시면 됩니다.
Ex) 문자 - 한 → U+D55C → 0xD55C : 1101 0101 0101 1100 → 3바이트 사용
→ 11101101 10010101 10011100 → 0xED 0x95 0x9C
# 파이썬 기본 문자열은 유니코드임
s = "A가😃"
# UTF-8로 인코딩 (문자 → 바이트)
encoded = s.encode('utf-8')
print(encoded) # b'A\xea\xb0\x80\xf0\x9f\x98\x83'
# UTF-8로 디코딩 (바이트 → 문자)
decoded = encoded.decode('utf-8')
print(decoded) # A가😃