UTF-16은 고정 너비 또는 가변 너비입니까? UTF-8에 바이트 순서 문제가없는 이유는 무엇입니까?


16
  1. UTF-16은 고정 너비 또는 가변 너비입니까? 다른 출처에서 다른 결과를 얻었습니다.

    에서 http://www.tbray.org/ongoing/When/200x/2003/04/26/UTF :

    UTF-16은 유니 코드 문자를 16 비트 청크로 저장합니다.

    에서 http://en.wikipedia.org/wiki/UTF-16/UCS-2 :

    UTF-16 (16 비트 유니 코드 변환 형식)은 유니 코드 코드 공간에서 0에서 0x10FFFF까지 1,112,064 [1] 숫자 (코드 포인트)를 인코딩 할 수있는 유니 코드 용 문자 인코딩입니다. 코드 포인트 당 하나 또는 두 개의 16 비트 코드 단위의 가변 길이 결과를 생성합니다.

  2. 첫 번째 출처에서

    UTF-8은 또한 인코딩 단위가 바이트라는 이점이 있으므로 바이트 순서 문제가 없습니다.

    UTF-8에 바이트 순서 문제가없는 이유는 무엇입니까? 가변 너비이며 한 문자에 둘 이상의 바이트가 포함될 수 있으므로 바이트 순서가 여전히 문제가 될 수 있다고 생각합니까?

감사합니다.


이 위대한 기사 절대 최소 모든 소프트웨어 개발자는 물론, 긍정적 유니 코드와 문자 집합에 대해 알고 있어야합니다 (변명!) 유니 코드와 UTF에 대한 모든 질문에 대한 답변 도움이 될 것입니다 ..
— Sorceror

답변:


13

(1) 바이트 순서는 C에서 char의 희귀를 의미합니까? UTF-16은 바이트 시퀀스입니까, 아니면 무엇입니까? (2) 바이트 시퀀스가 ​​가변 길이와 관련이없는 이유는 무엇입니까?

엔디안 문제가 무엇인지 오해하는 것 같습니다. 다음은 간단한 요약입니다.

32 비트 정수는 4 바이트를 차지합니다. 이제이 바이트들의 논리적 순서를 알았습니다. 32 비트 정수가있는 경우 다음 코드를 사용하여 상위 바이트를 얻을 수 있습니다.

uint32_t value = 0x8100FF32;
uint8_t highByte = (uint8_t)((value >> 24) & 0xFF); //Now contains 0x81

그게 다 잘 됐어 문제가 시작되는 곳은 다양한 하드웨어가 메모리에서 정수를 저장하고 검색하는 방법입니다.

Big Endian 순서로, 32 비트 정수로 읽는 4 바이트 메모리는 첫 바이트가 높은 바이트 인 상태에서 읽습니다.

[0][1][2][3]

리틀 엔디안 (Little Endian) 순서로, 32 비트 정수로 읽는 4 바이트 메모리는 첫 바이트가 낮은 바이트 로 읽 힙니다 .

[3][2][1][0]

32 비트 값에 대한 포인터가있는 경우 다음을 수행 할 수 있습니다.

uint32_t value = 0x8100FF32;
uint32_t *pValue = &value;
uint8_t *pHighByte = (uint8_t*)pValue;
uint8_t highByte = pHighByte[0]; //Now contains... ?

C / C ++에 따르면이 결과는 정의되어 있지 않습니다. 0x81 일 수 있습니다. 또는 0x32 일 수 있습니다. 기술적으로는 모든 것을 반환 할 수 있지만 실제 시스템의 경우 하나 또는 다른 것을 반환합니다.

메모리 주소에 대한 포인터가 있으면 해당 주소를 32 비트 값, 16 비트 값 또는 8 비트 값으로 읽을 수 있습니다. 빅 엔디안 머신에서 포인터는 높은 바이트를 가리 킵니다. 리틀 엔디안 머신에서 포인터는 하위 바이트를 가리 킵니다.

이것은 메모리에서 읽고 쓰는 것에 관한 것입니다. 내부 C / C ++ 코드와 는 아무런 관련 이 없습니다 . C / C ++에서 정의되지 않은 것으로 선언하지 않은 코드의 첫 번째 버전은 항상 높은 바이트를 얻기 위해 작동합니다.

바이트 스트림 읽기를 시작할 때 문제가 발생합니다. 파일에서와 같은.

16 비트 값은 32 비트와 같은 문제가 있습니다. 그것들은 단지 4 대신에 2 바이트를 갖는다. 따라서, 파일은 빅 엔디안 또는 리틀 엔디안 순서로 저장된 16 비트 값을 포함 할 수있다.

UTF-16은 일련의 16 비트 값으로 정의됩니다 . 효과적으로, 그것은입니다 uint16_t[]. 각 개별 코드 단위는 16 비트 값입니다. 따라서 UTF-16을 올바르게로드하려면 데이터의 엔디안이 무엇인지 알아야합니다.

UTF-8은 일련의 8 비트 값으로 정의됩니다 . 입니다 uint8_t[]. 각 개별 코드 단위의 크기는 8 비트이며 단일 바이트입니다.

이제 UTF-16과 UTF-8은 여러 코드 단위 (16 비트 또는 8 비트 값)를 함께 결합하여 유니 코드 코드 포인트 ( "문자")를 구성 할 수있게하지만 올바른 용어는 아닙니다 . 단순화입니다. ). 코드 포인트를 구성하는 이러한 코드 단위 의 순서 는 UTF-16 및 UTF-8 인코딩에 의해 결정됩니다.

UTF-16을 처리 할 때 16 비트 값을 읽고 필요한 엔디안 변환을 수행합니다. 그런 다음 대리 쌍인지 감지합니다. 그렇다면 다른 16 비트 값을 읽고 두 값을 결합하면 유니 코드 코드 포인트 값을 얻게됩니다.

UTF-8을 처리 할 때 8 비트 값을 읽습니다. 1 바이트 만 있기 때문에 엔디안 변환이 불가능합니다. 첫 번째 바이트가 멀티 바이트 시퀀스를 나타내는 경우 멀티 바이트 시퀀스에 의해 지시 된대로 일부 바이트 수를 읽습니다. 각 개별 바이트는 바이트이므로 엔디안 변환이 없습니다. 위해 이들은 UTF-16 게이트 쌍의 순서는, UTF-8에 의해 정의되는 것처럼 시퀀스 바이트.

따라서 UTF-8에는 엔디안 문제가 없습니다.


10

Jeremy Banks의 답변은 가능한 한 정확하지만 바이트 순서는 다루지 않았습니다.

UTF-16을 사용할 때 대부분의 글리프는 2 바이트 단어를 사용하여 저장되지만 단어가 디스크 파일에 저장 될 때 구성 바이트를 저장하는 데 어떤 순서를 사용합니까?

예를 들어, 단어 "water"에 대한 CJK (중국어) 글리프는 6C34의 16 진수로 UTF-16 인코딩을 갖습니다. 디스크에 2 바이트로 쓸 때 "big-endian"(2 바이트는 6C 34)으로 작성합니까? 아니면 "리틀 엔디안 (2 바이트는 34 6C)"이라고 쓰십니까?

UTF-16을 사용하면 두 순서가 합법적이며 일반적으로 파일의 첫 번째 단어를 BOM (Byte Order Mark)으로 만들어 파일의 단어를 지정합니다. 빅 엔디안 인코딩의 경우 FE FF이고 리틀 엔디안의 경우 인코딩은 FF FE입니다.

UTF-32는 동일한 문제와 동일한 솔루션을 가지고 있습니다.

UTF-8은 길이가 가변적이기 때문에이 문제가 없으며 글리프의 바이트 시퀀스를 리틀 엔디안 인 것처럼 효과적으로 작성할 수 있습니다. 예를 들어, 문자 "P"는 항상 1 바이트-80-를 사용하여 인코딩되고 대체 문자는 항상 2 바이트 FF FD를 사용하여 순서대로 인코딩됩니다.

일부 프로그램은 UTF-8 파일의 시작 부분에 3 바이트 표시기 (EF BB BF)를 넣고 ASCII와 같은 유사한 인코딩과 UTF-8을 구별하는 데 도움이되지만 MS Windows를 제외하고는 일반적이지 않습니다.


감사! (1) 문자 "P"는 UTF-8에서 단지 1 바이트입니다. 대체 문자가 코드에 추가되는 이유는 무엇입니까? (2) UTF-8에는 UTF-8에 둘 이상의 바이트가있는 다른 문자가 있습니다. 이러한 각 문자의 바이트 간 바이트 순서가 왜 문제가되지 않습니까?
— 모든 StackExchange for

@Tim : (1) P의 코드에 대체 문자를 추가하지 않습니다. 80 FF FD가 표시되면 P 문자와 대체 문자의 두 문자입니다.
— 밥 머피

(2) 항상 "교체 문자"에 대한 2 바이트를 FF FD 순서대로 쓰고 읽습니다. "교체 문자"를 FD FF로 쓸 수도 있다면 바이트 순서 문제 만있을뿐입니다. 이 2 바이트의 시퀀스는 "대체 문자"이외의 것입니다.
— 밥 머피

1
@ 팀 : en.wikipedia.org/wiki/UTF-8을 통해 작업하고 싶을 수도 있습니다 . 정말 좋으며 모든 유니 코드 관련 위키 백과 페이지를 이해할 수 있다면 더 이상 질문이 없다고 생각합니다.
— 밥 머피

4
UTF-8이 바이트 순서에 문제가없는 이유는 인코딩이 바이트 시퀀스로 정의 되고 엔디안이 다른 변형이 없기 때문입니다. 가변 길이와 관련이 없습니다.
— starblue
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.