[unicode] 유니 코드, UTF-8, UTF-16이란 무엇입니까?

유니 코드의 기초는 무엇이며 왜 UTF-8 또는 UTF-16이 필요한가? 나는 이것을 Google에서 조사하고 여기에서도 검색했지만 명확하지 않습니다.

VSS에서 파일 비교를 수행 할 때 두 파일의 UTF가 다르다는 메시지가 표시되는 경우가 있습니다. 왜 이런 경우입니까?

간단한 용어로 설명하십시오.



답변

왜 유니 코드가 필요한가요?

(그렇지 않은) 초기에는 존재했던 모든 것이 ASCII였습니다. 이 문장에서와 같이 몇 가지 제어 문자, 문장 부호, 숫자 및 문자 만 있으면되었으므로 괜찮습니다. 불행히도, 오늘날의 이상한 세계 상호 통신 및 소셜 미디어 세계는 예견되지 않았으며 영어, العربية, 汉语, עִבְרִית, ελληνικά 및 ភាសាខ្មែរ을 같은 문서에서 보는 것이 너무 이례적이지 않습니다. 브라우저).

그러나 논쟁을 위해 Joe Average는 소프트웨어 개발자라고 말합니다. 그는 영어 만 있으면되고 ASCII 만 사용하기를 원한다고 주장합니다. 사용자 Joe에게는 문제가 될 수 있지만 소프트웨어 개발자 Joe에게는 문제가되지 않습니다 . 세계의 약 절반이 라틴 문자가 아닌 문자를 사용하고 ASCII를 사용하는 것이이 사람들에게는 무시할 수없는 일이며, 게다가 그는 성장하는 경제에 소프트웨어를 폐쇄하고 있습니다.

따라서 모든 언어를 포함하는 문자 세트 가 필요합니다. 따라서 유니 코드가왔다. 모든 문자에 코드 포인트 라는 고유 번호를 할당합니다 . 다른 가능한 세트에 비해 유니 코드의 한 가지 장점은 첫 번째 256 코드 포인트가 ISO-8859-1 과 동일 하므로 ASCII도 있다는 것입니다. 또한, 일반적으로 사용되는 대부분의 문자는 BMP (Basic Multilingual Plane) 라는 영역에서 2 바이트로만 표현할 수 있습니다. 이제이 문자 집합에 액세스하려면 문자 인코딩이 필요하며 질문에 따라 UTF-8과 UTF-16에 집중할 것입니다.

메모리 고려 사항

그렇다면이 인코딩에서 몇 바이트가 어떤 문자에 액세스 할 수 있습니까?

  • UTF-8 :
    • 1 바이트 : 표준 ASCII
    • 2 바이트 : 아랍어, 히브리어, 대부분의 유럽 문자 (대부분 그루지야 어 제외 )
    • 3 바이트 : BMP
    • 4 바이트 : 모든 유니 코드 문자
  • UTF-16 :
    • 2 바이트 : BMP
    • 4 바이트 : 모든 유니 코드 문자

BMP에 포함되지 않은 문자에는 고대 스크립트, 수학 기호, 음악 기호 및 희귀 한자 / 일본어 / 한국어 (CJK) 문자가 포함됩니다.

주로 ASCII 문자로 작업하는 경우 UTF-8이 확실히 메모리 효율적입니다. 그러나 유럽 이외의 스크립트를 주로 사용하는 경우 UTF-8을 사용하면 UTF-16보다 메모리 효율성이 최대 1.5 배 떨어질 수 있습니다. 큰 웹 페이지 나 긴 단어 문서와 같이 많은 양의 텍스트를 처리 할 경우 성능에 영향을 줄 수 있습니다.

인코딩 기초

참고 : UTF-8 및 UTF-16의 인코딩 방식을 알고 있으면 실제 응용 프로그램의 다음 섹션으로 건너 뛰십시오.

  • UTF-8 : 표준 ASCII (0-127) 문자의 경우 UTF-8 코드는 동일합니다. 기존 ASCII 텍스트와의 호환성이 필요한 경우 UTF-8이 이상적입니다. 다른 문자는 2-4 바이트가 필요합니다. 이는 각 바이트에서 일부 비트를 예약하여 멀티 바이트 문자의 일부임을 나타냅니다. 특히, 각 바이트의 첫 번째 비트 1는 ASCII 문자와의 충돌을 피하는 것입니다.
  • UTF-16 : 유효한 BMP 문자의 경우 UTF-16 표현은 단순히 코드 포인트입니다. 그러나 BMP가 아닌 문자의 경우 UTF-16은 서로 게이트 쌍을 도입 합니다 . 이 경우 두 개의 2 바이트 부분 조합은 BMP가 아닌 문자에 맵핑됩니다. 이 2 바이트 부분은 BMP 숫자 범위에서 제공되지만 유니 코드 표준에서는 BMP 문자로 유효하지 않은 것으로 보장됩니다. 또한 UTF-16의 기본 단위는 2 바이트이므로 endianness의 영향을 받습니다 . 보상하기 위해, 예약 바이트 순서 마크 는 엔디안을 나타내는 데이터 스트림의 시작 부분에 배치 될 수있다. 따라서 UTF-16 입력을 읽고 엔디안을 지정하지 않은 경우이를 확인해야합니다.

알 수 있듯이 UTF-8과 UTF-16은 서로 거의 호환되지 않습니다. 따라서 I / O를 수행하는 경우 사용중인 인코딩을 알고 있어야합니다! 이러한 인코딩에 대한 자세한 내용은 UTF FAQ 를 참조하십시오 .

실제 프로그래밍 고려 사항

문자 및 문자열 데이터 유형 : 프로그래밍 언어로 어떻게 인코딩됩니까? 원시 바이트 인 경우 비 ASCII 문자를 출력하려고 시도하는 순간 몇 가지 문제가 발생할 수 있습니다. 또한 문자 유형이 UTF를 기반으로하더라도 문자열이 올바른 UTF임을 의미하지는 않습니다. 잘못된 바이트 시퀀스를 허용 할 수 있습니다. 일반적으로 C, C ++ 및 Java 용 ICU 와 같은 UTF를 지원하는 라이브러리를 사용해야합니다 . 어쨌든 기본 인코딩 이외의 것을 입력 / 출력하려면 먼저 변환해야합니다.

권장 / 기본 / 주요 인코딩 : 사용할 UTF를 선택하면 일반적으로 작업중인 환경에 권장되는 표준을 따르는 것이 가장 좋습니다. 예를 들어 UTF-8은 웹에서 지배적이며 HTML5부터는 왔다 권장 인코딩 . 반대로 .NET 및 Java 환경은 모두 UTF-16 문자 유형으로 구성됩니다. 혼란스럽고 (잘못), 종종 “유니 코드 인코딩”이 언급되는데, 이것은 일반적으로 주어진 환경에서 지배적 인 UTF 인코딩을 말합니다.

라이브러리 지원 : 사용중인 라이브러리는 일종의 인코딩을 지원합니다. 어느 것? 그들은 코너 케이스를 지원합니까? 필요성은 발명의 어머니이기 때문에 UTF-8 라이브러리는 일반적으로 1, 2 및 3 바이트 문자가 자주 발생할 수 있으므로 4 바이트 문자를 올바르게 지원합니다. 그러나 모든 의도 된 UTF-16 라이브러리는 대리 쌍이 거의 발생하지 않기 때문에 대리 쌍을 올바르게 지원하지는 않습니다.

계산 문자 : 유니 코드 에는 결합 문자 가 있습니다 . 예를 들어, 코드 포인트 U + 006E (n) 및 U + 0303 (결합 물결표)은 n ~을 형성하지만 코드 포인트 U + 00F1은 ñ를 형성합니다. 그것들은 동일하게 보이지만, 간단한 카운팅 알고리즘은 첫 번째 예에서는 2를, 후자는 1을 반환합니다. 반드시 잘못된 것은 아니지만 원하는 결과가 아닐 수도 있습니다.

평등 비교 : A, А 및 A는 동일하게 보이지만 각각 라틴어, 키릴 어 및 그리스어입니다. C와 Ⅽ와 같은 경우가 있습니다. 하나는 문자이고 다른 하나는 로마 숫자입니다. 또한 고려할 결합 문자도 있습니다. 자세한 내용 은 유니 코드에서 문자 복제를 참조하십시오 .

대리 쌍 : 이것들은 종종 SO에서 충분히 나오므로 몇 가지 예제 링크를 제공합니다.

다른 사람? :


답변

  • 유니 코드
    • 전 세계에서 사용되는 문자 집합입니다
  • UTF-8
    • 가능한 모든 문자 (코드 포인트)를 유니 코드로 인코딩 할 수있는 문자 인코딩
    • 코드 단위는 8 비트입니다
    • 1-4 개의 코드 단위를 사용하여 유니 코드를 인코딩하십시오.
    • $ “(1 개의 8 비트)의 경우 00100100 ; ” ¢ “(2 개의 8 비트)에 대해 11000010 10100010 ; ” “의 경우 11100010 10000010 10101100 (3 개의 8 비트)
  • UTF-16
    • 다른 문자 인코딩
    • 코드 단위는 16 비트입니다
    • 1 ~ 2 개의 코드 단위를 사용하여 유니 코드를 인코딩
    • $ “(1 개의 16 비트)의 경우 00000000 00100100 ; ” 101 “의 경우 11011000 01010010 11011111 01100010 (2 개의 16 비트)

답변

유니 코드는 상당히 복잡한 표준입니다. 너무 두려워하지 말고 어떤 일을 준비하십시오! [2]

신뢰할만한 자료가 항상 필요하지만 공식 보고서는 방대하기 때문에 다음을 읽어 보는 것이 좋습니다.

  1. 절대 최소의 모든 소프트웨어 개발자는 반드시 유니 코드 및 문자 집합에 대해 반드시 알아야합니다 (변명 없음) 스택 교환 CEO Joel Spolsky의 소개.
  2. BMP 이상으로! 당시 유니 코드 컨소시엄의 기술 담당 이사 인 Eric Muller의 튜토리얼. (처음 20 슬라이드 완료되었습니다)

간단한 설명 :

컴퓨터는 바이트를 읽고 사람들은 문자를 읽으므로 인코딩 표준 을 사용 하여 문자를 바이트에 매핑합니다. ASCII는 가장 널리 사용되는 표준이지만 라틴 문자 만 포함합니다 (7 비트 / 문자는 128 개의 다른 문자를 나타낼 수 있음). 유니 코드는 세계에서 가능한 모든 문자를 포함하는 것을 목표로하는 표준입니다 (최대 1,114,112 자, 최대 21 비트 / 문자를 의미 할 수 있습니다. 현재 유니 코드 8.0은 총 120,737자를 지정합니다).

주요 차이점은 ASCII 문자는 바이트 (8 비트)에 맞지만 대부분의 유니 코드 문자는 맞지 않는다는 것입니다. 따라서 UTF-8 및 UTF-16과 같은 인코딩 형식 / 체계가 사용되며 문자 모델은 다음과 같습니다.

모든 문자는 code point 라는 0에서 1,114,111 (16 진 : 0-10FFFF)의 열거 된 위치를 보유합니다 . 인코딩 형식은 코드 부 시퀀스에 대한 코드 포인트에 매핑한다. 코드 단위는 당신이 문자 메모리, 8 비트 단위, 16 비트 단위로 구성 등등 싶은 방법입니다. UTF-8은 1 비트에서 4 단위의 8 비트를 사용하고 UTF-16은 16 비트의 1 또는 2 단위를 사용하여 최대 21 비트의 전체 유니 코드를 포함합니다. 단위는 접두사를 사용하여 문자 경계를 찾을 수 있으며 더 많은 단위는 비트를 차지하는 더 많은 접두사를 의미합니다. 따라서 UTF-8은 라틴 스크립트에 1 바이트를 사용하지만 Basic Multilingual Plane의 이후 스크립트에는 3 바이트가 필요하지만 UTF-16은이 모든 것에 2 바이트를 사용합니다. 그리고 이것이 그들의 주요 차이점입니다.
마지막으로 인코딩 체계

(UTF-16BE 또는 UTF-16LE와 같은)는 코드 단위 시퀀스를 바이트 시퀀스에 매핑 (직렬화)합니다.

문자 : π
코드 포인트 : U + 03C0
인코딩 형식 (코드 단위) :
      UTF-8 : CF 80
      UTF-16 : 03C0
인코딩 체계 (바이트) :
      UTF-8 : CF 80
      UTF-16BE : 03 C0
      UTF-16LE : C0 03

팁 : 16 진수는 4 비트를 나타내므로 2 자리 16 진수는 1 바이트를 나타냅니다.
또한 Wikipedia의 Plane map을 살펴보면 문자 세트 레이아웃을 느낄 수 있습니다.


답변

원래 유니 코드는 고정 너비 16 비트 인코딩 (UCS-2)을 갖도록 설계되었습니다. Java 및 Windows NT와 같은 초기 유니 코드 채택자는 라이브러리를 약 16 비트 문자열로 구축했습니다.

나중에 유니 코드의 범위는 기록 문자를 포함하도록 확장되어 16 비트 인코딩이 지원하는 65,536 개 이상의 코드 포인트가 필요합니다. UCS-2를 사용한 플랫폼에서 추가 문자를 표시 할 수 있도록 UTF-16 인코딩이 도입되었습니다. “서로 게이트 쌍”을 사용하여 보조 평면의 문자를 나타냅니다.

한편 많은 구형 소프트웨어 및 네트워크 프로토콜은 8 비트 문자열을 사용하고있었습니다. UTF-8은 이러한 시스템이 넓은 문자를 사용하지 않고도 유니 코드를 지원할 수 있도록 만들어졌습니다. 7 비트 ASCII와 역 호환됩니다.


답변

이 기사는 모든 세부 사항을 설명합니다
http://kunststube.net/encoding/

버퍼 쓰기

UTF8 인코딩 을 사용하여 4 바이트 버퍼, 기호에 쓰면 바이너리는 다음과 같습니다.

00000000 11100011 10000001 10000010

UTF16 인코딩 을 사용하여 4 바이트 버퍼, 기호에 쓰면 바이너리는 다음과 같습니다.

00000000 00000000 00110000 01000010

보시다시피, 콘텐츠에 사용할 언어에 따라 메모리에 영향을 미칩니다.

예를 들어이 특정 심볼의 경우 : 다음 심볼에 사용할 여분의 바이트가 2 개이므로 UTF16 인코딩이 더 효율적입니다. 그러나 일본 알파벳에 UTF16을 사용해야한다는 의미는 아닙니다.

버퍼에서 읽기

위의 바이트를 읽으려면 어떤 인코딩으로 작성되었는지 알고 올바르게 다시 디코딩해야합니다.

이를 디코딩하는 경우 예를 들면 :
00,000,000 11,100,011 10,000,001 10,000,010
UTF16 인코딩에, 당신은으로 끝날 것 없다

참고 : 인코딩과 유니 코드는 서로 다른 두 가지입니다. 유니 코드는 각 기호가 고유 한 코드 포인트에 매핑 된 큰 (테이블) 입니다. 예를 들어, 기호 (문자)는 (코드 포인트) : 30 42 (16 진수)입니다. 반면 인코딩은 하드웨어에 저장할 때 기호를보다 적절한 방식으로 변환하는 알고리즘입니다.

30 42 (hex) - > UTF8 encoding - > E3 81 82 (hex), which is above result in binary.

30 42 (hex) - > UTF16 encoding - > 30 42 (hex), which is above result in binary.

여기에 이미지 설명을 입력하십시오


답변

유니 코드 는 모든 언어의 문자를 Code Points 라는 특정 숫자 값에 매핑하는 표준입니다 . 그렇게하는 이유는 동일한 코드 포인트 세트를 사용하여 다른 인코딩이 가능하기 때문입니다.

UTF-8 및 UTF-16은 이러한 두 가지 인코딩입니다. 코드 포인트를 입력으로 사용하고 인코딩 된 문자열을 생성하기 위해 잘 정의 된 수식을 사용하여 인코딩합니다.

특정 인코딩을 선택하는 것은 요구 사항에 따라 다릅니다. 인코딩에 따라 다른 메모리 요구 사항이 있으며 처리 할 문자에 따라 최소 바이트 시퀀스를 사용하여 해당 문자를 인코딩하는 인코딩을 선택해야합니다.

유니 코드, UTF-8 및 UTF-16에 대한 자세한 내용은이 기사를 참조하십시오.

모든 프로그래머가 유니 코드에 대해 알아야 할 사항


답변

왜 유니 코드인가? ASCII는 127 자에 불과합니다. 국가마다 128에서 255까지 차이가 ​​있으므로 코드 페이지가있는 이유입니다. 그래서 그들은 최대 1114111자를 사용할 수 있다고 말했습니다. 그렇다면 가장 높은 코드 포인트를 어떻게 저장합니까? 21 비트를 사용하여 저장해야하므로 11 비트가 낭비 된 32 비트의 DWORD를 사용합니다. 따라서 DWORD를 사용하여 유니 코드 문자를 저장하는 경우 DWORD의 값이 코드 포인트와 정확히 일치하므로 가장 쉬운 방법입니다. 그러나 DWORD 배열은 물론 WORD 배열보다 크고 BYTE 배열보다 훨씬 큽니다. utf-32뿐만 아니라 utf-16도있는 이유입니다. 그러나 utf-16은 WORD 스트림을 의미하며 WORD에는 16 비트가 있으므로 가장 높은 코드 포인트 1114111은 WORD에 어떻게 맞을 수 있습니까? 그럴 순 없어! 그래서 그들은 65535 이상의 모든 것을 DWORD에 넣습니다. 이러한 대리 쌍은 두 개의 단어이며 처음 6 비트를 보면 감지 할 수 있습니다. utf-8은 어떻습니까? 바이트 배열 또는 바이트 스트림이지만 어떻게 가장 높은 코드 포인트 1114111을 바이트에 맞출 수 있습니까? 그럴 순 없어! 좋아, 그래서 그들은 또한 DWORD를 넣었습니까? 아니면 단어일까요? 거의 그렇습니다! 그들은 utf-8 시퀀스를 발명했습니다. 즉, 127보다 높은 모든 코드 포인트는 2 바이트, 3 바이트 또는 4 바이트 시퀀스로 인코딩되어야합니다. 와! 그러나 어떻게 그러한 서열을 탐지 할 수 있습니까? 127까지의 모든 것은 ASCII이며 단일 바이트입니다. 110으로 시작하는 것은 2 바이트 시퀀스이고 1110으로 시작하는 것은 3 바이트 시퀀스이며 11110으로 시작하는 것은 4 바이트 시퀀스입니다. 소위 “startbytes”의 나머지 비트는 코드 포인트에 속합니다. 이제 순서에 따라 다음 바이트가 따라 와야합니다. 다음 바이트는 10으로 시작합니다. 나머지 비트는 6 비트 페이로드 비트이며 코드 포인트에 속합니다. 시작 바이트와 다음 바이트의 페이로드 비트를 연결하면 코드 포인트가 생깁니다. 이것이 utf-8의 모든 마법입니다.