UTF-8로 인코딩 할 수있는 문자는 몇 개입니까?


97

UTF-8이 8 비트이면 최대 256 개의 문자 만있을 수 있다는 의미가 아닙니까?

처음 128 개의 코드 포인트는 ASCII에서와 동일합니다. 그러나 UTF-8은 최대 백만 개의 문자를 지원할 수 있다고 말합니다.

어떻게 작동합니까?


2
모든 답변이 틀 렸기 때문에이 질문을 재평가 해 주시면 감사하겠습니다. 내 대답을 읽어 stackoverflow.com/a/45042566/124486
에반 캐롤

유니 코드의 UTF-8, UTF-16, UTF-32 인코딩에서 숫자는 코드 단위 의 비트 수이며 그중 하나 이상이 유니 코드 코드 포인트를 인코딩합니다.
Tom Blodget

1
나는이 질문을 바로 잡기 위해 얼마 전에 대답했다. 말 그대로 전체 이야기를 말하지 않는 하나의 위키피디아 인용문 인 선택된 대답과 비교해 보면 좋을 것이다. ) 많은 명확
에반 캐롤

답변:


135

UTF-8은 항상 1 바이트를 사용하지 않으며 1-4 바이트입니다.

처음 128 자 (US-ASCII)에는 1 바이트가 필요합니다.

다음 1,920 개의 문자를 인코딩하려면 2 바이트가 필요합니다. 여기에는 거의 모든 라틴 알파벳의 나머지 부분과 그리스어, 키릴 어, 콥트어, 아르메니아어, 히브리어, 아랍어, 시리아 어 및 타나 어 알파벳과 분음 부호 결합이 포함됩니다.

대부분의 중국어, 일본어 및 한국어 [CJK] 문자를 포함하여 거의 모든 공통 문자 [12]를 포함하는 나머지 기본 다국어 평면의 문자에는 3 바이트가 필요합니다.

덜 일반적인 CJK 문자, 다양한 역사적 스크립트, 수학 기호 및 이모티콘 (그림 기호)을 포함하는 유니 코드의 다른 평면에있는 문자에는 4 바이트가 필요합니다.

출처 : Wikipedia


안녕 @zwippie 나는 이것에 처음이다. 내가 이해하지 못하는 것이 있습니다.! BMP는 2 바이트를 사용합니다. 내가 잘못?
chiperortiz 2019 년

1
@chiperortiz, BMP는 실제로 16 비트이므로 문자 당 길이가 일정한 UTF-16으로 인코딩 할 수 있습니다 (UTF-16은 16 비트 이상을 지원하지만 어려운 관행이며 많은 구현에서 지원하지 않습니다). 그러나 UTF-8의 경우 길이도 인코딩해야하므로 약간의 손실이 발생합니다. 이것이 전체 BMP를 인코딩하는 데 3 바이트가 필요한 이유입니다. 이것은 낭비적인 것처럼 보일 수 있지만 UTF-16은 항상 2 바이트를 사용하지만 UTF-8은 대부분의 라틴 기반 언어 문자에 대해 문자 당 1 바이트를 사용합니다. 두 배로 작게 만듭니다.
sanderd17

OP 질문의 주된 요지는 UTF- 8 이라고 불리는 이유와 관련 이 있습니다. 이것은 실제로 대답하지 않습니다.
jbyrd

40

UTF-8은 문자 당 1-4 바이트를 사용합니다. ASCII 문자의 경우 1 바이트입니다 (처음 128 개의 유니 코드 값은 ascii와 동일 함). 하지만 7 비트 만 필요합니다. 가장 높은 ( "부호") 비트가 설정되면 멀티 바이트 시퀀스의 시작을 나타냅니다. 연속적인 상위 비트 세트의 수는 바이트 수를 나타내고 그 다음에는 0을 나타내며 나머지 비트가 값에 기여합니다. 다른 바이트의 경우 가장 높은 두 비트는 1과 0이고 나머지 6 비트는 값입니다.

따라서 4 바이트 시퀀스는 11110 ... (및 ... = 값에 대해 3 비트)로 시작하고 값에 대해 각각 6 비트가있는 3 바이트로 21 비트 값을 생성합니다. 2 ^ 21은 유니 코드 문자 수를 초과하므로 모든 유니 코드를 UTF8로 표현할 수 있습니다.


@NickL. 아니요, 3 바이트를 의미합니다. 멀티 바이트 시퀀스의 첫 번째 바이트 1,111을 시작하는 경우 그 실시 예에서, (1) 첫 번째는 것을 나타내고 있다 멀티 바이트 시퀀스의 시작, 그 후 연속 된 1 개의 개수는 수 나타내는 부가 제 그래서 시퀀스에서 바이트 ( 바이트는 110, 1110 또는 11110으로 시작됩니다).
CodeClown42

RFC 3629. tools.ietf.org/html/rfc3629#section-3 에서 귀하의 단어에 대한 증거를 찾았 습니다 . 그러나 두 번째 바이트 110xxxxx 10xxxxxx의 시작 부분에 "10"을 입력해야하는 이유를 이해할 수 없습니다. 왜 110xxxxx xxxxxxxx가 아닌가?
kolobok 2017.11.06

3
softwareengineering.stackexchange.com/questions/262227/… 에서 답변을 찾았습니다 . 그냥 안전을 위해 (경우에 스트림의 중간에 단일 바이트가 손상)
kolobok

@kolobok 아. Sans 안전을 사용하면 21 비트 값을 3 바이트 (길이를 나타내는 3 비트에 21 비트를 더한 값)로 인코딩 할 수 있습니다. : D 아마도 WRT 서구 언어로는 그다지 의미가 없을 것입니다.
CodeClown42 2017

나는 NickL이 이것을 물었다 고 생각하지만 ...가 비트 대신 후속 바이트를 나타내는 경우 해당 첫 번째 바이트의 나머지 비트는 어떻게 되었습니까?
c6754

27

이 표 에 따르면 * UTF-8 은 다음을 지원 해야 합니다.

2 31 = 2,147,483,648 자

그러나, RFC 3629는 그래서 지금 우리가하고, 가능한 값을 제한 4 바이트에 덮인 우리를 준다,

2 21 = 2,097,152 자

이러한 문자의 좋은 덩어리는 사용자 정의 사용을 위해 "예약"되어 있으며 실제로 아이콘 글꼴에 매우 편리합니다.

* 사용 된 Wikipedia는 6 바이트의 테이블을 보여줍니다. 이후 기사를 업데이트했습니다.

2017-07-11 : 여러 바이트로 인코딩 된 동일한 코드 포인트를 이중 계산하도록 수정 됨


이 대답은 가능한 인코딩 수를 두 배로 세는 것입니다. 2 ^ 7을 모두 계산하면 2 ^ 11, 2 ^ 16 등에서 다시 계산할 수 없습니다. 가능한 올바른 인코딩 수는 2 ^ 21입니다 (현재 모두 사용되지는 않음).
Jimmy

@Jimmy 내가 이중으로 세는 게 확실해? 0xxxxxxx7 개의 사용 가능한 비트를 110xxxxx 10xxxxxx제공하고 11 개의 비트를 더 제공합니다. 겹치는 부분이 없습니다. 첫 번째 바이트 0는 첫 번째 경우와 1두 번째 경우에서 시작합니다.
mpen

@mpen 그래서 어떤 코드 포인트가 00000001저장하고 무엇을 11000000 100000001저장합니까?
Evan Carroll

1
@EvanCarroll Uhh .... 포인트 촬영. 동일한 코드 포인트를 인코딩하는 여러 가지 방법이 있다는 사실을 몰랐습니다.
mpen

1
: 나는에 앞서 당신이이 질문에 대한 더 나은 설명과 답변을 생각하는지, 자신이 대답을 시도했다 stackoverflow.com/a/45042566/124486
에반 캐롤

21

유니 코드 대 UTF-8

유니 코드는 코드 포인트를 문자로 해석합니다. UTF-8은 유니 코드를위한 저장 메커니즘입니다. 유니 코드에는 사양이 있습니다. UTF-8에는 사양이 있습니다. 둘 다 다른 한계가 있습니다. UTF-8은 상향 바인딩이 다릅니다.

유니 코드

유니 코드는 "평면" 으로 지정됩니다 . 각 비행기에는 2 개의 16 개의 코드 포인트가 있습니다. 유니 코드에는 17 개의 평면이 있습니다. 총17 * 2^16 코드 포인트. 첫 번째 평면 인 평면 0 또는 BMP 는 운반하는 무게가 특별합니다.

모든 뉘앙스를 설명하기보다는 위의 기사를 비행기에 대해 인용하겠습니다.

17 개의 평면은 1,114,112 개의 코드 포인트를 수용 할 수 있습니다. 이 중 2,048 개는 대리자이고 66 개는 비 문자이며 137,468 개는 개인용으로 예약되어 있으며 974,530 개는 공개 할당 용으로 남겨집니다.

UTF-8

이제 위에 링크 된 기사로 돌아가 보겠습니다.

UTF-8에서 사용하는 인코딩 체계는 2 31 코드 포인트 (32,768 플레인) 의 훨씬 더 큰 제한으로 설계되었으며 2 21을 인코딩 할 수 있습니다. 4 바이트로 제한 되더라도 코드 포인트 (32 플레인)를 . [3] 유니 코드는 UTF-16으로 인코딩 할 수있는 17 개의 평면으로 코드 포인트를 제한하므로 0x10FFFF 이상의 코드 포인트는 UTF-8 및 UTF-32에서 유효하지 않습니다.

따라서 유효한 유니 코드가 아닌 것을 UTF-8에 넣을 수 있음을 알 수 있습니다. 왜? UTF-8은 유니 코드가 지원하지 않는 코드 포인트를 수용하기 때문입니다.

UTF-8은 4 바이트 제한이 있어도 2 21 코드 포인트를 지원합니다.17 * 2^16


19

2,164,864 개의 "문자"는 잠재적으로 UTF-8로 코딩 될 수 있습니다.

이 숫자는 2 ^ 7 + 2 ^ 11 + 2 ^ 16 + 2 ^ 21이며 인코딩이 작동하는 방식에서 비롯됩니다.

  • 1 바이트 문자는 인코딩을위한 7 비트 0xxxxxxx(0x00-0x7F)

  • 2 바이트 문자는 인코딩을위한 11 비트 110xxxxx 10xxxxxx(첫 번째 바이트의 경우 0xC0-0xDF, 두 번째 바이트의 경우 0x80-0xBF)

  • 3 바이트 문자는 인코딩을위한 16 비트 1110xxxx 10xxxxxx 10xxxxxx(첫 번째 바이트의 경우 0xE0-0xEF, 연속 바이트의 경우 0x80-0xBF)입니다.

  • 4 바이트 문자는 인코딩을 위해 21 비트 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx를가집니다 (첫 번째 바이트는 0xF0-0xF7, 연속 바이트는 0x80-0xBF).

보시다시피 현재 유니 코드 (1,112,064 자)보다 훨씬 큽니다.

최신 정보

추가 규칙을 고려하지 않기 때문에 초기 계산이 잘못되었습니다. 자세한 내용은이 답변에 대한 의견을 참조하십시오.


2
수학은 가장 짧은 코드 단위 시퀀스 만 코드 포인트를 인코딩 할 수 있다는 UTF-8 규칙을 따르지 않습니다. 따라서 00000001은 U + 0001에 유효하지만 11110000 10000000 10000000 10000001은 유효하지 않습니다. 참고 : 표 3-7. 잘 구성된 UTF-8 바이트 시퀀스 . 게다가, 질문은 표에 의해 직접 답변됩니다. 범위를 더하면됩니다. (UTF-16의 서로 게이트를 제외하기 위해 분리되어 있습니다.)
Tom Blodget

Tom-귀하의 의견에 감사드립니다! 나는 그러한 제한을 알지 못했습니다. 나는 보았다 표 3-7숫자를 실행 하며 1083392 개 가능한 유효한 시퀀스가있는 것 같습니다.
Ruben Reyes

6

UTF-8은 문자 당 최소 8 비트 의 가변 길이 인코딩입니다 . 코드 포인트가 더 높은 문자는 최대 32 비트를 차지합니다.


2
이것은 오해의 소지가 있습니다. 사용할 수있는 가장 긴 코드 포인트는 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx이므로 실제 문자를 인코딩하는 데 21 비트 만 사용할 수 있습니다.
Boris

5
코드 포인트는 인코딩하는 데 최대 32 비트가 걸릴 수 있다고 말했지만 (유도에 의해) 32 비트 UTF-8로 2 ^ 32 문자를 인코딩 할 수 있다고 주장한 적이 없습니다. 하지만 기존의 모든 유니 코드 문자를 UTF-8로 인코딩 할 있고 UTF-8을 48 비트 (존재하지만 더 이상 사용되지 않음)로 확장하면 더 많이 인코딩 할 있기 때문에 다소 문제가 있습니다. 오해의 소지가있는 점입니다.
deceze


2

유니 코드 표준 및 FAQ 항목, UTF-8 UTF-16, UTF-32 및 BOM 과 같은 관련 정보를 확인하십시오. . 순조로운 항해는 아니지만 권위있는 정보이며 다른 곳에서 UTF-8에 대해 읽을 수있는 내용의 대부분은 의심 스럽습니다.

"UTF-8"의 "8"은 코드 단위 의 길이와 관련이 있습니다. 비트 . 코드 단위는 문자를 인코딩하는 데 사용하는 엔티티이며 반드시 단순한 일대일 매핑이 아닙니다. UTF-8은 다양한 수의 코드 단위를 사용하여 문자를 인코딩합니다.

UTF-8로 인코딩 할 수있는 문자 모음은 UTF-16 또는 UTF-32, 즉 모든 유니 코드 문자와 정확히 동일합니다. 이들은 모두 전체 유니 코드 코딩 공간을 인코딩하며, 여기에는 문자가 아닌 코드 포인트와 할당되지 않은 코드 포인트도 포함됩니다.


1

현재 최대 UTF-8 코드 (2,164,864)에 대해 mpen에 동의하지만 (아래에 나열되어 있지만 이에 대해 언급 할 수 없음) UTF-8의 두 가지 주요 제한 사항을 제거하면 2 단계로 떨어집니다 : 단 4 바이트 제한 및 코드 254 및 255는 사용할 수 없습니다 (4 바이트 제한 만 제거).

시작 코드 254는 기본 시작 비트 배열 (1로 설정된 다중 비트 플래그, 6 1의 개수, 터미널 0, 예비 비트 없음)을 따라 작업 할 6 개의 추가 바이트를 제공합니다 (6 개의 10xxxxxx 그룹, 추가 2 ^ 36 코드).

시작 코드 255는 기본 설정을 정확히 따르지 않고 터미널 0이 없지만 모든 비트가 사용되어 7 개의 추가 바이트를 제공합니다 (모든 비트가 사용되기 때문에 다중 비트 플래그가 1로 설정되고 1의 개수가 7이고 터미널 0이 없음). ; 7 개의 10xxxxxx 그룹, 추가 2 ^ 42 코드).

이를 추가하면 표시 가능한 최종 최대 문자 집합은 4,468,982,745,216입니다. 이것은 현재 사용되는 모든 문자, 오래된 언어 또는 죽은 언어, 믿어지지 않는 언어보다 많습니다. Angelic 또는 Celestial 스크립트 누구?

또한 254 및 255 : 128-191 및 기타 몇 가지 외에도 UTF-8 표준에서 간과 / 무시되는 단일 바이트 코드가 있습니다. 일부는 키보드에서 로컬로 사용되며 예제 코드 128은 일반적으로 삭제 백 스페이스입니다. 다른 시작 코드 (및 관련 범위)는 하나 이상의 이유로 유효하지 않습니다 ( https://en.wikipedia.org/wiki/UTF-8#Invalid_byte_sequences ).


0

유니 코드는 UTF-8과 확고하게 결합되었습니다. 유니 코드는 특히 UTF-8에서 지원하는 코드 포인트 수와 정확히 동일한 2 ^ 21 코드 포인트 (2,097,152 자)를 지원합니다. 두 시스템 모두 코드 포인트 등에 대해 동일한 '데드'공간과 제한 구역을 예약합니다. 2018 년 6 월 현재 가장 최근 버전 인 유니 코드 11.0에는 137,439 자의 레퍼토리가 포함되어 있습니다.

유니 코드 표준에서. 유니 코드 FAQ

유니 코드 표준은 21 비트 코드 공간에 해당하는 U + 0000..U + 10FFFF 범위의 문자를 인코딩합니다.

UTF-8 Wikipedia 페이지에서. UTF-8 설명

2003 년 유니 코드 코드 공간이 21 비트 값으로 제한 되었기 때문에 UTF-8은 코드 포인트를 1-4 바이트로 인코딩하도록 정의되었습니다.


21 비트는 반올림됩니다. 유니 코드는 1,114,112 개의 코드 포인트 (U + 0000 ~ U + 10FFFF)를 지원합니다. (때때로 65536의 17 개 비행기로 설명 됨.)
Tom Blodget

@TomBlodget, 당신이 맞습니다. 이 논의에서 가장 관련이있는 점은 UTF-8이 현재 정의 된 모든 유니 코드 포인트를 유니 코드 표준으로 인코딩 할 수 있으며 앞으로 꽤 오랫동안 그렇게 할 수 있다는 것입니다.
표시 이름
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.