유니 코드로 몇 개의 문자를 매핑 할 수 있습니까?


82

설명과 함께 유니 코드로 가능한 모든 유효한 조합의 개수를 요청하고 있습니다. 나는 문자가 1,2,3 또는 4 바이트로 인코딩 될 수 있다는 것을 알고 있습니다. 또한 해당 문자의 시작 바이트가 얼마나 오래되어야하는지 지워도 연속 바이트에 제한이있는 이유를 이해하지 못합니다.

답변:


118

설명과 함께 유니 코드로 가능한 모든 유효한 조합의 개수를 요청하고 있습니다.

1,111,998 : 평면 17 개 × 평면 당 65,536 자-대리 2048 개-비 문자 66 개

UTF-8 및 UTF-32는 이론적으로 17 개 이상의 플레인을 인코딩 할 수 있지만 범위는 UTF-16 인코딩제한 에 따라 제한 됩니다.

실제로 137,929 개의 코드 포인트가 유니 코드 12.1로 할당됩니다 .

또한 해당 문자의 시작 바이트가 얼마나 오래되어야하는지 지워도 연속 바이트에 제한이있는 이유를 이해하지 못합니다.

UTF-8에서이 제한의 목적은 인코딩이 자체 동기화되도록하는 것 입니다.

반례로 중국 GB 18030 인코딩을 고려하십시오 . 여기서 문자 ß81 30 89 38숫자 0및 의 인코딩을 포함하는 바이트 시퀀스로 표시됩니다 8. 따라서이 인코딩 특정 특성을 위해 설계되지 않은 문자열 검색 기능이있는 경우 숫자 8를 검색 하면 문자 내에서 잘못된 긍정이 발견됩니다 ß.

UTF-8에서는 리드 바이트와 트레일 바이트 사이의 비 중첩이 더 짧은 문자의 인코딩이 더 긴 문자의 인코딩 내에서 발생하지 않도록 보장하기 때문에 발생할 수 없습니다.


2
링크 한 "자체 동기화"기사는 자체 동기화가 무엇인지 전혀 설명하지 않습니다
Pacerier

흥미로운 점처럼 UTF8은 모든 유니 코드 문자를 매핑하는 데 4 바이트 만 필요하지만 UTF8은 필요한 경우 최대 680 억 문자를 지원할 수 있으며 문자 당 최대 7 바이트를 차지합니다.
santiago arizti

10

유니 코드는 각각 65,536 개의 문자 (또는 '코드 포인트')의 17 개 플레인을 허용합니다 . 이것은 총 1,114,112 개의 가능한 문자를 제공합니다. 현재이 공간의 약 10 % 만 할당되었습니다.

이러한 코드 포인트가 인코딩되는 방법에 대한 정확한 세부 사항은 인코딩에 따라 다르지만 귀하의 질문은 UTF-8을 생각하는 것처럼 들립니다. 연속 바이트에 대한 제한 이유는 아마도 다음 문자의 시작을 쉽게 찾을 수 있기 때문입니다 (연속 문자는 항상 10xxxxxx 형식이지만 시작 바이트는이 형식이 될 수 없습니다).


이 "플레인"에 따르면 4 바이트 문자의 마지막 3 바이트조차도 64 개를 표현할 수 있습니다. 내가 잘못?
Ufuk Hacıoğulları

예, 동기화를위한 것입니다. cl.cam.ac.uk/~mgk25/ucs/utf-8-history.txt
ninjalj

2
제 생각에는 구식입니다. 더 이상 6 바이트를 사용하지 않습니다
Ufuk Hacıoğulları

3
@Andy : 말이됩니다. UTF-8의 원래 사양은 더 큰 숫자를 위해 작동했습니다. 21 비트 제한은 16 비트 문자로 자신을 고정한 사람들에게 흠뻑 젖었 고 UCS-2는 UTF-16으로 알려진 혐오감을 낳았습니다.
tchrist

1
@Simon : 34 개의 비 문자 코드 포인트가 있습니다. 0xFFFE == 0xFFFE로 비트 단위로 추가 된 것이므로 평면 당 두 개의 코드 포인트가 있습니다. 또한 0x00_FDD0 .. 0x00_FDEF 범위에 31 개의 비 문자 코드 포인트가 있습니다. 또한 UTF-16 결함으로 인해 개방형 교환에 합법적이지 않지만 프로그램 내에서 지원되어야하는 대리자에서 빼야합니다.
tchrist

5

유니 코드는 1,114,112 코드 포인트를 지원합니다. 1,112,064 스칼라 값을 제공하는 2048 개의 서로 게이트 코드 포인트가 있습니다. 이 중 66 개의 비 문자가있어 1,111,998 개의 인코딩 된 문자가 가능합니다 (계산 오류가없는 경우).


내 대답을 볼 수 있습니까? 코드 포인트가 1,112,114 개인 이유는 무엇입니까?
Ufuk Hacıoğulları

3
이 번호는 UTF-16 대리 시스템을 사용하여 주소를 지정할 수있는 평면 수에서 비롯됩니다. 1024 개의 낮은 서로 게이트와 1024 개의 높은 서로 게이트가있어 1024² 비 BMP 코드 포인트를 제공합니다. 여기에 65,536 BMP 코드 포인트를 더하면 정확히 1,114,112가 제공됩니다.
Philipp

2
@Philipp,하지만 답에 '1_112_114'를 주 셨는데 댓글에 '1_114_112'를 설명하셨습니다. 아마도 당신은 2와 4 혼합
숀 코바치를

1
이 대답은 수년 동안 계산 오류와 함께 앉아 있었으므로 자유롭게 정리할 수있었습니다. 예, 답변의 1112114 값이 오타였습니다. 올바른 값은 0x110000의 10 진수 값인 1114112입니다.
Ray Toal

1

은유 적으로 정확한 답을 제공하려면 all of them.

UTF-8 인코딩의 연속 바이트는 "라인 노이즈"에 직면하여 인코딩 된 옥텟 스트림의 재 동기화를 허용합니다. 인코더는 다음 바이트가 새 문자 포인트의 시작임을 알기 위해 0x80과 0xBF 사이의 값이없는 바이트를 앞으로 스캔하기 만하면됩니다.

이론적으로 오늘날 사용되는 인코딩은 유니 코드 문자 번호가 최대 31 비트 길이 인 문자의 표현을 허용합니다. 실제로이 인코딩은 실제로 Twitter와 같은 서비스에서 구현되며 최대 길이의 트윗은 최대 4,340 비트의 데이터를 인코딩 할 수 있습니다. (140 자 [유효 및 유효하지 않음], 각각 31 비트 곱하기)


이론적으로는 31 비트로 제한되지 않고 64 비트 머신에서 더 커질 수 있습니다. perl -le 'print ord "\x{1FFF_FFFF_FFFF}"'64 비트 컴퓨터에서는 35184372088831을 인쇄하지만 32 비트 컴퓨터에서는 정수 오버플로를 제공합니다. perl 프로그램 내에서 이와 같은 더 큰 문자를 사용할 수 있지만 utf8로 인쇄하려고하면 비활성화하지 않는 한 필수 경고가 표시됩니다 perl -le 'print "\x{1FFF_FFFF}"' Code point 0x1FFFFFFF is not Unicode, may not be portable at -e line 1. ######.. "loose utf8"과 "strict UTF-8"사이에는 차이가 있습니다. 전자는 제한되지 않습니다.
tchrist

1
오늘날 사용되는 인코딩은 31 비트 스칼라 값을 허용하지 않습니다. UTF-32는 32 비트 값을 허용하고 UTF-8은 더 많은 것을 허용하지만 UTF-16 (Windows, OS X, Java, .NET, Python에서 내부적으로 사용되므로 가장 널리 사용되는 인코딩 체계)은 그 이상을 허용합니다. 100 만 (여전히 충분해야 함).
Philipp

1
"모두"는 정확하지 않습니다. 유니 코드가 아닌 레거시 인코딩에 문자가 있습니다. 예를 들어 MacRoman의 Apple 로고와 ATASCII의 그래픽 문자 몇 개가 있습니다. OTOH, 개인 사용 영역이 있으므로 이러한 문자 를 유니 코드로 매핑 할 수 있습니다. 그것들은 표준의 일부가 아닙니다.
dan04

1
@tchrist : Python 3는 UTF-16을 사용합니다. 예를 들어, 내 시스템에서 len(chr(0x10000))2 (코드 단위)를 제공하여 라고 말할 수 있습니다 . OS X의 커널은 올바른 UTF-8을 사용하지만 높은 수준의 API (Cocoa 등)는 UTF-16을 사용합니다.
Philipp

1
@Philip : 저는 유니 코드 지원이 많이 필요한 Python 2 만 사용합니다. 저는 시스템 전문가이므로 최종 사용자 크롬 도금을하지 않습니다. OS X에서 사용하는 모든 시스템 호출은 커널이 NFC로 변환하는 UTF-8을 사용합니다. Java에서의 UTF-16 경험은 나빴습니다. 리터럴에서 BMP가 아닌 코드 포인트와 정규식 괄호로 묶인 charclass 일치를 시도하면 [𝒜-𝒵]UTF-16을 허물로 노출하는 이유를 알 수 있습니다. 프로그래머가 논리 문자 대신 인코딩 형식으로 생각하게 만드는 것은 실수입니다.
tchrist


1

Wikipedia 에 따르면 유니 코드 12.1 (2019 년 5 월 출시)에는 137,994 개의 고유 문자가 포함되어 있습니다.


@Ufuk : 유니 코드에는 문자가 없습니다. 코드 포인트가 있습니다. 때로는 하나의 문자를 구성하기 위해 여러 코드 포인트가 필요합니다. 예를 들어, 문자 "5 ~"는 두 개의 코드 포인트 인 반면, 문자 "ñ"은 하나 또는 두 개의 코드 포인트 (또는 그 이상!) 일 수 있습니다. 2²¹ 가능한 코드 포인트가 있지만 일부는 비 문자 또는 부분 문자로 예약되어 있습니다.
tchrist 22:57에

6
유니 코드는 문자 인코딩 표준입니다. unicode.org/faq/basic_q.html의 첫 번째 답변 :“유니 코드는 범용 문자 인코딩입니다.”그래서“유니 코드는 인코딩이 아닙니다”라는 말은 잘못되었습니다. (나는 한 번 그 실수 나 자신했다.)
필립

1
@tchrist : 유니 코드 표준은 "추상 문자"와 "인코딩 된 문자"중에서 여러 용어를 정의합니다. 따라서 유니 코드에 문자가 없다는 것도 사실이 아닙니다.
Philipp
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.