UTF-8 인코딩 문자의 최대 바이트 수는 얼마입니까?


79

단일 UTF-8 인코딩 문자의 최대 바이트 수는 얼마입니까?

UTF-8로 인코딩 된 String의 바이트를 암호화하므로 UTF-8로 인코딩 된 String의 최대 바이트 수를 계산할 수 있어야합니다.

누군가가 단일 UTF-8 인코딩 문자의 최대 바이트 수를 확인할 수 있습니까?


1
당신은 같은 공통 자원, 봐 위키 백과의 UTF-8 조 , 첫 ... 괜찮아?

5
나는 혼합 된 답변을 제공하는 여러 기사를 읽었습니다 ... 실제로 대답이 3이라는 인상을
받았기

2
Tom Scott의 문자, 기호, 유니 코드 기적 : goo.gl/sUr1Hf를 소개하는 YouTube 링크를 여기에 남겨 드리겠습니다 . 모든 것이 ASCII 문자 인코딩에서 utf-8로 어떻게 진화하고 있는지 듣고 볼 수 있습니다.
로이 리

길이 계산 코드 예제는 실제로 인코딩하지 않고 Java String의 UTF-8로 길이 계산을 참조하십시오
Vadzim

답변:


86

문자 테이블을 다음으로 제한 한 RFC3629 에 따라 문자 당 최대 바이트 수는 4입니다 U+10FFFF.

UTF-8에서 U + 0000..U + 10FFFF 범위 (UTF-16 액세스 가능 범위)의 문자는 1-4 옥텟의 시퀀스를 사용하여 인코딩됩니다.

(원래 사양에서는 코드 포인트에 대해 최대 6 바이트 문자 코드를 허용했습니다 U+10FFFF.)

코드가 128 미만인 문자는 1 바이트 만 필요하고 다음 1920 문자 코드에는 2 바이트 만 필요합니다. 난해한 언어로 작업하지 않는 한 문자 수에 4를 곱하면 상당한 과대 평가가됩니다.


7
당신을위한 "불쾌 언어"는 무엇입니까? 현실 세계에 존재하는 언어 또는 세계의 다른 언어 사이를 전환하는 텍스트? UTF-8-to-String 함수의 개발자가 초과 할당을 수행하고 실제 변환 후 결과를 축소하는 경우 곱셈기로 2, 3 또는 4를 선택해야합니까?
Daniel Marschall 2014-06-06

1
@rinntech by '비교적 언어'는 고 부가가치 유니 코드 문자가 많은 언어를 의미합니다 (이 목록의 하단 근처에있는 것 : unicode-table.com/en/sections ). 과도하게 할당해야하는 경우 4를 선택하십시오. 이중 패스를 수행 할 수 있습니다. 하나는 필요한 바이트 수를 확인하고 할당하고 다른 하나는 인코딩을 수행합니다. 필요한 RAM의 최대 4 배를 할당하는 것보다 낫습니다.
matiu

9
항상 최악의 경우를 처리하려고 : hacker9.com/single-message-can-crash-whatsapp.html
Evgen Bodunov

20
CJKV 문자는 대부분 3 바이트를 사용하며 (일부 희귀 / 고풍 문자는 4 바이트를 사용함) 난해하다고 부르는 것은 다소 무리입니다 (중국 만 세계 인구의 거의 20 %입니다 ...).
Tgr

3
이전에 6이었을 때 4로 제한되었던 이유는 무엇입니까? 우리가 표준을 계속하고 문자 를위한 선행 바이트 111111112^(6*7)약간의 공간을 갖는 것을 막는 것은 무엇입니까 ?
Aaron Franke

32

더 이상의 컨텍스트가 없으면 UTF-8 문자의 최대 바이트 수는 다음과 같습니다.

답변 : 6 바이트

받아 들여진 답변의 저자는 이것을 "원래 사양"이라고 정확하게 지적했습니다. 이는 RFC-2279 1을 통해 유효했습니다 . J. Cocoe가 아래 주석에서 지적했듯이 2003 년에 RFC-3629 2로 변경되었습니다 . 이는 UTF-8을 21 비트 인코딩으로 제한하고 4 바이트를 사용하는 인코딩 체계로 처리 할 수 ​​있습니다.

모든 유니 코드를 포함하는 경우 응답 : 4 바이트

그러나 Java <= v7 에서는 UTF-8로 유니 코드를 나타내는 최대 3 바이트에 대해 이야기합니다. 원래 유니 코드 사양은 기본 다국어 플레인 ( BMP ) 만 정의했기 때문입니다. 즉, 유니 코드의 이전 버전 또는 최신 유니 코드의 하위 집합입니다. 그래서

원래 유니 코드 만 나타내는 경우 응답 BMP : 3 바이트

그러나 OP는 다른 방향으로가는 것에 대해 이야기합니다. 문자에서 UTF-8 바이트로가 아니라 UTF-8 바이트에서 "문자열"의 바이트 표현으로. 아마도 받아 들여진 대답의 저자는 질문의 맥락에서 그것을 얻었을 것입니다. 그러나 이것이 반드시 명백한 것은 아니므로이 질문의 평범한 독자를 혼란스럽게 할 수 있습니다.

UTF-8에서 네이티브 인코딩으로 이동하면서 "String"이 구현되는 방식을 살펴 봐야합니다. Python> = 3과 같은 일부 언어는 정수 코드 포인트로 각 문자를 나타내므로 문자 당 4 바이트 = 32 비트를 사용하여 유니 코드에 필요한 21 개를 처리 할 수 ​​있습니다. 정확히 21 비트가 아닌 이유는 무엇입니까? 왜냐하면 바이트로 정렬되면 더 빠르기 때문입니다. Python <= 2 및 Java 와 같은 일부 언어 는 UTF-16 인코딩을 사용하여 문자를 나타냅니다. 즉, BMP가 아닌 확장 유니 코드를 나타내려면 서로 게이트 쌍을 사용해야합니다. 어느 쪽이든 여전히 최대 4 바이트입니다.

UTF-8-> 기본 인코딩 : 4 바이트

따라서 최종 결론은 4가 가장 일반적인 정답이므로 정답입니다. 그러나 마일리지는 다를 수 있습니다.


5
"이것은 여전히 ​​wikipedia에 따라 현재의 정확한 사양입니다"-더 이상은 아닙니다. 이 글을 쓴 직후 (4 월 2 일 편집), 6 옥텟 버전이 현재 (2003) UTF-8 사양의 일부가 아님을 명확히하기 위해 Wikipedia의 UTF-8 기사가 변경되었습니다.
J. Cocoe

"그러나 Java <= v7에서는 UTF-8로 유니 코드를 표현하는 데 최대 3 바이트에 대해 이야기합니다. 원래 유니 코드 사양이 기본 다국어 플레인 만 정의했기 때문입니다."-아마도 원래 이유 일 것입니다. 전체 이야기가 아닙니다. Java는 "수정 된 UTF-8"을 사용하며 수정 사항 중 하나는 "표준 UTF-8의 4 바이트 형식"(그들의 단어) 대신 "자신의 2 배 3 바이트 형식을 사용"한다는 것입니다.
J. Cocoe

1
10FFFF (백만 개가 조금 넘는) 제한을 초과하여 할당 된 코드 포인트가 없으며 많은 UTF8 구현이 4 바이트 (그리고 MySQL과 같은 3 개만)보다 긴 시퀀스를 구현하지 않았으므로 당 4 바이트로 하드 제한하는 것이 안전하다고 생각합니다. 이전 구현과의 호환성을 고려할 때도 코드 포인트. 들어가는 도중에 유효하지 않은 것은 버리도록해야합니다. 정확한 바이트 길이를 계산 한 후 할당하라는 matiu의 권장 사항은 가능한 한 좋은 것입니다.
thomasrutter

2
"... [U] nicode는 최대 x10FFFF 코드 포인트를 나타낼 수 있습니다. 따라서 0을 포함하면 F FF FF, 즉 2 바이트 반 또는 20 비트 바이트로 수행 할 수 있습니다." 나는 이것이 약간 잘못 되었다고 생각합니다 . 0x0에서 0x10FFFF까지의 코드 포인트 수는 0x110000이되며, 이는 1F FF FF21 비트로 표현 될 수 있습니다 . 0x110000 번호는 각각 0x10000 코드 포인트 의 17 개 평면 에 해당합니다 .
neuralmer

2
PSA : 위키 백과는 실제 출처가 아닙니다. 기사의 실제 참조를보십시오.
Nyerguds

0

표준 영어 알파벳 인코딩 인 US-ASCII를 지원하는 최대 바이트 수는 1입니다. 그러나 시간이 지남에 따라 텍스트를 영어로 제한하는 것은 바람직하지 않거나 실용적이지 않습니다.

유니 코드는 다양한 렌더링 특성을 사용하여 모든 인간 언어의 글리프와 여러 종류의 기호를 나타내도록 설계되었습니다. UTF-8은 여전히 ​​영어로 편향되어 있지만 유니 코드를위한 효율적인 인코딩입니다. UTF-8은 자체 동기화됩니다. 문자 경계는 어느 방향 으로든 잘 정의 된 비트 패턴을 스캔하여 쉽게 식별됩니다.

UTF-8 문자 당 최대 바이트 수는 Plane 0, BMP (Basic Multilingual Plane)의 2 바이트 주소 공간 만 지원하는 경우 3이고 일부 응용 프로그램에서는 최소 지원으로 허용 될 수 있습니다. 현재 유니 코드의 17 개 평면 모두 (2019 년 기준). 많은 인기있는 "이모 지"문자는 4 바이트가 필요한 Plane 16에있을 가능성이 높습니다.

그러나 이것은 기본 문자 글리프에만 해당됩니다. 또한 이전 문자 위에 악센트를 표시하는 것과 같은 다양한 수정자가 있으며, 임의의 수의 코드 포인트를 함께 연결하여 하나의 복잡한 "문자 소"를 구성 할 수도 있습니다. 따라서 실제 프로그래밍에서 문자 당 고정 된 최대 바이트 수를 사용하거나 가정하면 결국 응용 프로그램에 문제가 발생할 수 있습니다.

이러한 고려 사항은 처리 전에 UTF-8 문자열이 고정 길이의 배열로 "확장"되어서는 안된다는 것을 의미합니다. 대신 UTF-8 용으로 특별히 설계된 문자열 함수를 사용하여 프로그래밍을 직접 수행해야합니다.


참고 : 고정 너비 문자 배열을 사용하지 않는 것에 대한 단락은 내 의견입니다. 의견에 대한 응답으로이 답변을 편집 할 의향이 있습니다.
David Spector
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.