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.