유니코드 정리
ASCII는 7비트로 구성된 문자 인코딩 체계로, 초기 컴퓨터 시스템에서 널리 사용되었다.
ASCII는 총 128개의 문자를 나타낼 수 있고, 각 문자는 0~127까지의 숫자 코드로 표현된다.
ASCII 코드
유니코드 : 컴퓨터에서 문자를 표현하는 국제 표준이다.
유니코드는 ASCII의 확장이고
각 문자마다 고유한 번호를 부여하는 방식으로 동작하는데, 이를 '코드 포인트' 라고 한다.
유니코드는 UTF-8,UTF-16, UTF-32 등의 인코딩 방식이 있다.
UTF-8이 가장 널리 사용되는 유니코드 인코딩 방식인데
아스키 코드와의 호환성 및 가변 길이 문자 인코딩의 이점 때문에 인기가 있다.
UTF - 8
: 유니코드를 8비트 단위로 나눠서 인코딩한다.
ASCII 문자들은 1바이트로, 다른 문자들은 최대 4바이트까지 사용할 수 있다.
UTF-8의 주요 특징
1. 변동길이 인코딩: UTF-8은 문자에 따라 1바이트에서 4바이트까지 변동하는 길이의 인코딩을 사용한다. 기본 ASCII 문자는 1바이트를 사용하며, 다른 다양한 문자들은 2바이트 이상을 사용한다.
2. 하위 호환성: UTF-8은 ASCII와 완전히 호환된다. 즉, 기존의 ASCII 텍스트는 UTF-8 인코딩된 텍스트로 취급할 수 있으며, 반대도 마찬가지다.
3. 자체 복구 기능: UTF-8 인코딩은 바이트 순서에 의해 문자의 시작과 끝을 결정하므로, 데이터가 손실되거나 변경된 경우에도 복구가 가능하다.
4. 전 세계 문자 지원: UTF-8은 전 세계의 거의 모든 문자를 지원하므로, 다양한 언어와 기호를 하나의 문서나 메시지에서 사용할 수 있다.
UTF-8 인코딩 규칙
- UTF-8 2-byte Characters
- 첫 번째 byte = 0xc0 ~ 0xdf
- 두 번째 byte = 0x80 ~ 0xbf
- UTF-8 3-byte Characters
- 첫 번째 byte = 0xe0 ~ 0xef
- 두 번째 byte = 0x80 ~ 0xbf
- 세 번째 byte = 0x80 ~ 0xbf
- UTF-8 4-byte Characters
- 첫 번째 byte = 0xf0 ~ 0xf7
- 두 번째 byte = 0x80 ~ 0xbf
- 세 번째 byte = 0x80 ~ 0xbf
- 네 번째 byte = 0x80 ~ 0xbf
- 코드 포인트 U+0000부터 U+007F까지(ASCII 범위)의 경우, UTF-8은 단일 바이트를 사용한다. 예를 들어, 'A'의 코드 포인트인 U+0041은 UTF-8에서 41이 된다(마커비트는 bit position7인데 값은 0).
- 코드 포인트 U+0080부터 U+07FF까지는 2바이트를 사용한다. 첫 번째 바이트는 110[마커비트]으로 시작하고 두 번째 바이트는 10으로 시작한다. 나머지 비트는 코드 포인트를 표현하는 데 사용된다.
- 코드 포인트 U+0800부터 U+FFFF까지는 3바이트를 사용한다. 첫 번째 바이트는 1110[마커비트]으로 시작하고, 두 번째와 세 번째 바이트는 각각 10으로 시작한다. 나머지 비트는 코드 포인트를 표현하는 데 사용된다.
- 코드 포인트 U+10000부터 U+10FFFF까지는 4바이트를 사용한다. 첫 번째 바이트는 11110[마커비트]으로 시작하고, 두 번째, 세 번째, 네 번째 바이트는 각각 10으로 시작한다. 나머지 비트는 코드 포인트를 표현하는 데 사용된다.
UTF - 16
: 각 문자를 16비트 단위로 인코딩 하는 방식이다.
BMP는 인코딩 하지않는다.
Surrogate Pairs
UTF-16 인코딩 방식은 마커 비트를 사용하지 않는다. UTF-8과는 달리, UTF-16은 서로게이트 쌍(surrogate pairs)라는 메커니즘을 사용하여 16비트 범위를 넘는 코드 포인트(U+10000~U+10FFFF : Supplementary Planes)를 인코딩한다.
UTF-16에서 서로게이트 쌍은 U+10000부터 U+10FFFF 범위의 코드 포인트를 인코딩하기 위해 사용된다. 이 범위의 코드 포인트는 두 개의 16비트 단위로 인코딩되는데, 첫 번째 단위는 U+D800부터 U+DBFF 범위에서, 두 번째 단위는 U+DC00부터 U+DFFF 범위에서 선택된다.
1. U' = Code Point -0x10000 = (0x0 ~ 0xFFFFF) : 20bit 영역만 남김
2. W1 = 상위 10-bit(0x0 ~ 0x03FF) + 0xD800 : High Surrogate(0xD800 ~ 0xDBFF)
3. W2 = 하위 10-bit(0x0 ~ 0x03FF) + 0xDC00 : Low Surrogate(0xDC00~0xDFFF)
U+10437()을 UTF-16으로 인코딩하려면:
- 코드 포인트에서 0x10000을 빼면 0x0437이 남는다.
- 상위 서로게이트의 경우 오른쪽으로 10만큼 이동(0x400으로 나누기)한 다음 0xD800을 추가하여 0x0001 + 0xD800 = 0xD801이 된다.
- 하위 서로게이트의 경우 하위 10비트(0x400으로 나눈 나머지)를 취한 다음 0xDC00을 추가하여 0x0037 + 0xDC00 = 0xDC37이 된다.
UTF-16에서 U+10437()을 디코딩하려면:
- 상위 대리(0xD801)에서 0xD800을 뺀 다음 0x400을 곱하면 0x0001 × 0x400 = 0x0400이 된다.
- 로우 대리(0xDC37)에서 0xDC00을 빼면 0x37이 된다.
- 이 두 결과를 함께 더하고(0x0437), 마지막으로 0x10000을 더하여 최종 코드 포인트인 0x10437을 얻는다.
따라서 UTF-16에서는 "마커 비트" 대신 이러한 특별한 코드 포인트 범위를 사용하여 다중 단위 문자를 인코딩하고 식별한다. 이는 UTF-16의 디코딩을 복잡하게 만드는 한편, 문자 단위와 코드 포인트가 일치하지 않는 경우를 생성함으로써 다양한 처리 문제를 유발할 수 있다.