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




유니코드 변환 (8)

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

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

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

유니 코드, UTF-8 및 UTF-16에 대한 자세한 내용은이 기사를 체크 아웃 할 수 있습니다.

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

유니 코드의 기초는 무엇이며 UTF-8 또는 UTF-16의 필요성은 무엇입니까? 나는 이것을 Google에서 연구했고 여기에서도 검색했지만 나에게 명확하지 않다.

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

간단히 설명하십시오.


유니 코드가 필요한 이유는 무엇입니까?

초창기에는 존재했던 모든 것이 ASCII였습니다. 이 문장에있는 것과 같은 몇 가지 제어 문자, 구두점, 숫자 및 문자 만 필요할 것이므로 괜찮 았습니다. 불행하게도 오늘날의 세계적인 상호 커뮤니케이션 및 소셜 미디어의 이상한 세계는 예견되지 않았으며 같은 문서에서 영어, العربية, 汉语, עִבְרִית, ελληνικά 및 see을 보는 것은 너무 드문 일이 아닙니다. 브라우저).

그러나 논쟁을 위해 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 바이트 : 아랍어, 히브리어, 대부분의 유럽어 스크립트 (특히 Georgian 제외)
    • 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 바이트를 필요로합니다. 이 작업은 멀티 바이트 문자의 일부임을 나타 내기 위해 이러한 각 바이트의 일부 비트를 예약하여 수행됩니다. 특히 ASCII 문자와의 충돌을 피하기 위해 각 바이트의 첫 번째 비트는 1 입니다.
  • UTF-16 : 유효한 BMP 문자의 경우 UTF-16 표현은 코드 포인트 일뿐입니다. 그러나 비 BMP 문자의 경우 UTF-16은 서로 게이트 쌍을 도입 합니다 . 이 경우 두 개의 2 바이트 부분 조합이 비 BMP 문자에 매핑됩니다. 이 2 바이트 부분은 BMP 숫자 범위에서 왔지만 유니 코드 표준에 의해 BMP 문자로 유효하지 않음이 보장됩니다. 또한 UTF-16은 기본 단위로 2 바이트를 endianness 때문에 endianness 영향을 endianness . 이를 보완하기 위해, 예약 된 바이트 순서 마크 를 엔디안을 나타내는 데이터 스트림의 시작 부분에 배치 할 수 있습니다. 따라서 UTF-16 입력을 읽었을 때 엔디안이 지정되지 않은 경우이를 확인해야합니다.

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

실용적인 프로그래밍 고려 사항

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

권장 / 기본 / 주요 인코딩 : 사용할 UTF를 선택할 때 일반적으로 작업 환경에 대한 권장 표준을 따르는 것이 가장 좋습니다. 예를 들어 UTF-8이 웹에서 지배적이며 HTML5 이후로는 UTF- 추천 된 인코딩 입니다. 반대로 .NET 및 Java 환경은 모두 UTF-16 문자 유형을 기반으로합니다. 혼란스럽게도 (그리고 부정확하게) 참조는 대개 "유니 코드 인코딩"으로 이루어지며, 이는 보통 주어진 환경에서 지배적 인 UTF 인코딩을 참조합니다.

도서관 지원 : 귀하가 사용하고있는 도서관의 인코딩은 무엇입니까? 그들은 코너 케이스를지지합니까? 필연적으로 발명품의 모체이기 때문에 UTF-8 라이브러리는 일반적으로 1, 2 및 심지어 3 바이트 문자가 자주 발생할 수 있기 때문에 일반적으로 4 바이트 문자를 올바르게 지원합니다. 그러나 모든 UTF-16 라이브러리가 아주 거의 발생하지 않기 때문에 서로 게이트 쌍을 제대로 지원하는 것은 아닙니다.

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

평등에 대한 비교 : A, А, Α는 같지만 라틴어, 키릴 어 및 그리스어입니다. 당신은 C와 cases 같은 경우도 있고, 하나는 문자이고, 다른 하나는 로마 숫자입니다. 또한, 고려해야 할 결합 문자가 있습니다. 자세한 내용 은 유니 코드의 중복 문자를 참조하십시오.

서로 게이트 쌍 (surrogate pairs) : 이렇게 자주 올라와 있으므로 몇 가지 예제 링크 만 제공합니다.

기타 ?:


원래 유니 코드는 고정 너비의 16 비트 인코딩 (UCS-2)을 사용했습니다. Java 및 Windows NT와 같은 초기 유니 코드 채택 자들은 16 비트 문자열 주위에 라이브러리를 만들었습니다.

나중에 유니 코드의 범위가 확장되어 16 비트 인코딩이 지원할 65,536 개 이상의 코드 포인트가 필요한 역사적인 문자가 포함되었습니다. UCS-2를 사용하는 플랫폼에서 추가 문자를 나타낼 수 있도록 UTF-16 인코딩이 도입되었습니다. 보충 비행기의 문자를 나타 내기 위해 "서로 게이트 쌍"을 사용합니다.

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


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

신뢰할 수있는 리소스가 항상 필요하지만 공식 보고서가 방대하기 때문에 다음을 읽는 것이 좋습니다.

  1. 모든 소프트웨어 개발자가 절대적으로 최소의 절대적으로, 유니 코드와 문자 집합에 대해 적극적으로 알아야 함 (변명의 여지가 없음) Stack Exchange CEO 인 Joel Spolsky의 소개.
  2. BMP와 그 이상! 나중에 The Unicode Consortium의 부회장 인 Eric Muller의 테크니컬 디렉터. (처음 20 슬라이드와 당신이 완료되었습니다)

간단한 설명 :

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

가장 큰 차이점은 ASCII 문자가 바이트 (8 비트)에 맞을 수 있지만 대부분의 유니 코드 문자는 사용할 수 없다는 것입니다. 따라서 UTF-8 및 UTF-16과 같은 인코딩 양식 / 체계가 사용되며 문자 모델은 다음과 같이 진행됩니다.

모든 문자는 코드 포인트 라고하는 0에서 1,114,111 (16 진수 : 0-10FFFF)의 열거 된 위치를 유지합니다.
코드화 양식 은 코드 포인트를 코드 단위 순서 맵핑합니다. 코드 단위 는 메모리, 8 비트 단위, 16 비트 단위 등으로 문자를 구성하려는 방식입니다. UTF-8은 1 ~ 4 단위의 8 비트를 사용하며, UTF-16은 1 ~ 2 단위의 16 비트를 사용하여 전체 유니 코드의 최대 21 비트를 포함합니다. 단위는 문자 경계를 발견 할 수 있도록 접두사를 사용하고, 더 많은 단위는 비트를 차지하는 접두사를 더 많이 의미합니다. 따라서 UTF-8은 라틴 스크립트 용으로 1 바이트를 사용하지만 나중에 다국어 기본 플레인 내부 스크립트 용으로 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 maps를보고 캐릭터 세트 레이아웃에 대한 느낌을 얻으십시오.


UTF는 유니 코드 변환 형식 (Unicode Transformation Format)의 약자입니다. 근본적으로 오늘날의 세계에서는 수백 가지 언어로 작성된 스크립트가 있으며 이전에 사용 된 기본 ASCII에 포함되지 않은 형식이 있습니다. 따라서 UTF가 생겨났습니다.

UTF-8에는 문자 인코딩 기능이 있으며 코드 단위는 8 비트이지만 UTF-16의 경우에는 16 비트입니다.


왜 유니 코드인가? ASCII는 127자를 가지고 있기 때문에. 128 개에서 255 개까지 국가마다 다르므로 코드 페이지가 있습니다. 그래서 그들은 1114111 자까지 가질 수 있다고 말했다. 그렇다면 최고의 코드 포인트를 어떻게 저장합니까? 21 비트를 사용하여 저장해야하므로 32 비트와 11 비트 낭비가있는 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이며 1 바이트입니다. 110으로 시작하는 것은 2 바이트 시퀀스입니다. 1110으로 시작하는 것은 3 바이트 시퀀스이고, 11110으로 시작하는 것은 4 바이트 시퀀스입니다. 이러한 소위 "시작 바이트"의 나머지 비트는 코드 포인트에 속합니다. 이제 순서에 따라 다음의 바이트를 따라야합니다. 다음 바이트는 10으로 시작하고, 나머지 비트는 페이로드 비트의 6 비트이며 코드 포인트에 속합니다. 시작 바이트와 다음 바이트의 페이로드 비트를 연결하면 코드 포인트가 생깁니다. 그것은 utf-8의 모든 마술입니다.


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

버퍼에 쓰기

UTF8 인코딩을 사용하여 4 바이트 버퍼에 심볼을 쓰면 바이너리는 다음과 같이 보입니다.

00000000 11100011 10000001 10000010

UTF16 인코딩을 사용하여 4 바이트 버퍼에 심볼을 쓰면 바이너리는 다음과 같이 보입니다.

00000000 00000000 00110000 01000010

보시다시피 콘텐츠에 사용하는 언어에 따라 적절하게 메모리에 영향을 미칩니다.

예 :이 특정 기호 : 다음 기호에 사용할 예비 바이트가 2 개 있기 때문에 A UTF16 인코딩이 더 효율적입니다. 그러나 일본 알파벳에 UTF16을 사용해야한다는 것을 의미하지는 않습니다.

버퍼에서 읽기

이제 위의 바이트를 읽고 싶다면, 어떤 인코딩으로 쓰여졌는지 알아야하고 올바르게 다시 디코딩해야합니다.

예 : 00000000 11100011 10000001 10000010 을 UTF16 인코딩으로 디코딩하면 결국

참고 : 인코딩과 유니 코드는 두 가지 다른 점이 있습니다. 유니 코드는 각 심볼이 고유 한 코드 포인트에 매핑 된 큰 (table) 입니다. 예 : 기호 (문자)는 (코드 포인트) : 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.


이 질문에는 이미 백만 분의 1 답변이 있으며 그 중 대다수가 매우 유용하지만 BOM을 사용해야하는지 또는 사용하지 말아야하는지 명확히하려고했습니다.

앞에서 언급했듯이 문자열이 UTF-8인지 여부를 결정할 때 UTF BOM (Byte Order Mark)을 사용하면 어림짐작을 알 수 있습니다. 사용할 수있는 적절한 메타 데이터 (예 : charset="utf-8" )가 있으면 사용하고있는 정보를 이미 알고 있지만 그렇지 않으면 몇 가지 가정을 테스트하고 확인해야합니다. 여기에는 문자열이 오는 파일이 16 진수 바이트 코드 인 EF BB BF로 시작하는지 확인하는 작업이 포함됩니다.

UTF-8 BOM에 해당하는 바이트 코드가 발견되면 UTF-8이라고 가정 할만큼 확률이 높으므로 거기에서 이동할 수 있습니다. 그러나이 추측을 강요 당할 때 독서 중 추가 오류 검사는 무언가가 왜곡 될 경우를 대비하여 여전히 좋은 생각입니다. 입력 UTF-8 일 필요가 없다면 BOM은 UTF-8 (즉, latin-1 또는 ANSI)이 아닌 것으로 가정해야합니다. 그러나 BOM이 없으면 인코딩에 대해 유효성을 검사하여 UTF-8로 간주되는지 여부를 간단히 판별 할 수 있습니다.

BOM이 권장되지 않는 이유는 무엇입니까?

  1. 비 유니 코드인지 또는 부적합한 소프트웨어는 latin-1 또는 ANSI로 간주 할 수 있으며 문자열에서 BOM을 제거하지 않아 문제가 분명 발생할 수 있습니다.
  2. 실제로는 필요하지 않습니다 (내용이 호환되는지 확인하고 호환되는 인코딩을 찾을 수없는 경우 대체물로 항상 UTF-8을 사용합니다)

언제 BOM으로 인코딩 해야 합니까?

메타 데이터를 다른 방법 (charset 태그 또는 파일 시스템 메타를 통해)으로 기록 할 수없고 BOM과 같은 프로그램을 사용하는 경우 BOM으로 인코딩해야합니다. BOM이없는 것이 일반적으로 레거시 코드 페이지를 사용한다고 가정되는 Windows에서 특히 그렇습니다. BOM은 Office와 같은 프로그램에이 파일의 텍스트가 유니 코드임을 알려줍니다. 여기에 사용 된 인코딩이 있습니다.

문제가 발생하면 CSV 만 문제가되는 유일한 파일입니다. 프로그램에 따라 BOM이 있어야하거나 BOM이 없어야합니다. 예를 들어 Windows에서 Excel 2007 이상을 사용하는 경우 원활하게 열고 데이터를 가져올 필요가 없으면 BOM으로 인코딩해야합니다.





unicode encoding utf-8 utf-16