유니 코드 인코딩이 여러 개인 이유는 무엇입니까?


41

나는 유니 코드가 대부분의 이전 시도 (ASCII 등)에서 작은 주소 공간 (8 비트)으로 인해 많은 다른 인코딩을 갖는 전체 문제를 해결하도록 설계되었다고 생각했습니다.

그렇다면 왜 그렇게 많은 유니 코드 인코딩이 있습니까? UTF-8, UTF-16 등과 같은 (본질적으로) 동일한 버전의 여러 버전조차도.


11
UTF-8은 UTF-16과 다릅니다. 지구와 같은 행성을 가진 다른 태양계를 만나면 곧 목록이 커질 것입니다.
setzamora

1
@Joset : 우리는 이미 Klingon을 가지고 있습니다. BMP에는 대부분의 지구 언어가 있으며 평원 1,2에 약간의 유출이 있습니다. 현재의 이론이 정확하고 은하에 우주 여행을 사용할 수있는 지점에 도달하는 42 종의 지각 종이있는 경우 (따라서 첫 번째 접촉 허용) 모든 언어의 모든 문자를 UNICODE로 압착 할 수 있어야합니다 (확장 할 수 있다고 가정) 64 평원을 허용하는 21 ~ 22 비트). 우주 비행을 달성하지 못한 원시 종을 포함시키고 싶다면 10 비트의 버퍼 공간을 남겨 둡니다.
Martin York

7
@Kevin Hsu : UTF-7,8,16LE, 16BE, 32LE, 32BE. 따라서 최소한 6 개의 실제 인코딩이 존재합니다. UTF-9 및 UTF-18은 April Fools입니다.
MSalters

9
표준에 대한 좋은 점은 너무 많다는 것입니다.
Homde

1
유니 코드 및 인코딩 에 대한 Spolsky의 의견을 참조하십시오 .
MPelletier

답변:


29

사람들은 각 문자에 21 비트를 사용하고 싶지 않기 때문입니다. 모든 현대 시스템에서 이것은 본질적으로 문자 당 3 바이트를 사용하는 것을 의미하며 이는 사람들이 사용했던 것보다 3 배 이상이므로 유니 코드를 전혀 채택하지 않았습니다. 예를 들어 UTF-8은 레거시 ASCII 파일을 전혀 변환 할 필요가 없기 때문에 영어 텍스트에는 적합하지만 유럽 언어에는 유용하지 않으며 아시아 언어에는 거의 사용되지 않습니다.

따라서 기본적으로 단일 범용 인코딩과 단일 범용 문자 차트를 정의 할 수 있었지만 시장에서는이를 받아들이지 않았습니다.


8
+1 좋은 답변입니다. 진정으로 정직하게 말하면이 질문에 실제로 답하는 유일한 사람입니다. 다른 모든 대답은 모든 다른 유니 코드 인코딩에서 바이트가 어떻게 배치되는지에 관한 것입니다.
Jacek Prucia 12

역사적으로 이는 단순한 의견 불일치입니다. 그러나 오늘날 UTF-8 이외의 다른 용도로는 많이 사용되지 않지만 UTF-16이 공간을 덜 소비하는 이론적 시나리오가 있지만 큰 차이는 없으며 드문 경우입니다. 공간을 절약하려는 가장 눈에 띄는 곳은 웹 사이트를위한 공간이지만 UTF-8을 사용하면 가장 짧은 HTML 코드로 가득합니다. 예를 들어 Shift JIS일본어 웹 사이트를 UTF-8보다 작게 만드는 데 사용할 수 있지만 일본어 전용 문자 세트이기 때문에 작동합니다.
aaaaaaaaaaaa

2
사실도 아닙니다. 압축 형식은 실제로 전송 및 저장에만 사용됩니다. 응용 프로그램 내에서는 UCS-2 또는 UCS-4를 고정 폭으로 사용하지만 문자 당 2 또는 4 바이트를 차지하므로 UCS-2 또는 UCS-4를 사용하는 것이 더 일반적입니다. 따라서 응용 프로그램은 사용 편의성을 위해 공간을 기꺼이 포기합니다.
Martin York

but it is less useful for European languages, and of little use for Asian languages– 이것은 단지 잘못이다. "충분 함"이란 압축을 의미합니까? 그렇다면 UTF-8은 유럽 언어에 대해 더 나은 압축을 제공합니다. 모든 텍스트에는 단일 바이트 만 사용하는 공백과 문장 부호가 있기 때문입니다.
Nick Volynkin

37

유니 코드는 21 비트 문자 인코딩으로 각 코드 포인트가 글리프 (그래픽 표현)로 표시되는 "CodePoints"를 고유하게 설명합니다.

  • 평면에서 코드 포인트를 식별하는 데 사용되는 16 비트 (대부분의 코드 포인트는 평면 0에 있음).
  • 평면을 식별하는 5 비트

지원되는 인코딩은 다음과 같습니다.

  • UTF-8 (8 비트 값을 사용하여 각 포인트를 인코딩)
  • UTF-16 (16 비트 값을 사용하여 각 포인트를 인코딩)
  • UTF-32 (32 비트 값을 사용하여 각 포인트를 인코딩)

그러나 디코딩 할 때 어떤 인코딩을 사용하더라도 동일한 의미를 갖는 특정 코드 포인트로 다시 매핑됩니다 (이것이 멋지다).

UTF-8

이것은 가변 크기 형식입니다. 각 코드 포인트는 1-4 바이트로 표시됩니다.

UTF-16

이것은 가변 크기 형식입니다. "기본 다국어 평면"(BMP 또는 평면 0)의 코드 포인트는 1 개의 단일 16 비트 값으로 표시 될 수 있습니다. 다른 평면의 코드 포인트는 서로 게이트 쌍 (2 16 비트 값)으로 표시됩니다.

UTF-32

이것은 고정 크기 형식입니다. 모든 코드 포인트는 단일 32 비트 값으로 표시됩니다.


2
이 답변도 마음에 듭니다. 비슷한 것을 쓰고 있었지만 이것은 분명합니다. 또한 UTF-8은 ASCII 문자열이 자동으로 UTF-8이라는 점에서 유용합니다.
Kevin Hsu

4
평범한 것이 아닌 기본 다국어 비행기 입니다.
JSB ձոգչ

3
이것은 좋은 대답이지만, 여전히 "왜?"라는 질문을 구걸한다고 생각합니다. 더 자세히 설명하자면, UTF-32는 유니 코드 문자를 인코딩하는보다 직접적인 (일부는 더 쉬운 방법) 접근 방법이지만 각 문자가 모두 4 바이트를 차지하므로 많은 공간을 낭비합니다. UTF-8은 ASCII 훨씬 더 작고 이전 버전과 호환되지만 규칙적이지는 않습니다. 문자를 인코딩하는 데 1-4 바이트가 걸릴 수 있으므로 작업하기가 더 어려워집니다. UTF-16은 둘 사이의 일종의 하이브리드 방식이며, 주로 각각의 장단점이 있습니다.
mipadi

4
메모리 사용량 (가장 일반적인 문자는 1 바이트이므로 UTF-8이 가장 좋은 곳)과 처리 속도 (UTF-32가 가장 좋은 곳)는 모든 문자의 크기가 동일하므로 특정 최적화가 가능하고 완벽한 메모리에서 32 비트 정렬). 결과적으로 네트워크 프로토콜 및 파일 형식은 일반적으로 UTF-8 (대역폭 / 저장 공간 절약)을 사용하는 반면 스크립트 인터프리터 및 언어 런타임은 UTF-16 또는 UTF-32를 선호 할 수 있습니다.
tdammers

2
@Marcel : "CodePoint"는 "CodePoint"가 아닙니다 character(문자가 여러 "CodePoints"로 구성 될 수 있음). 두 용어를 혼동하지 마십시오. 그러나 올바른 "CodePoints"는 글리프를 참조하지 않습니다. 글리프는 코드 포인트를 그래픽으로 표현한 것입니다. 미묘하지만 중요한 차이점.
Martin York

25

두 가지 아이디어를 분리하는 것이 유용하다고 생각합니다.

  1. 유니 코드-전 세계의 문자를 코드 포인트에 매핑
  2. 인코딩-코드 포인트를 비트 패턴 (UTF-8, UTF-16 등)에 매핑

UTF-8, UTF-16 및 기타 인코딩에는 각각 고유 한 장단점이 있습니다. 그것에 대해 Wikipedia 에 문의 하는 것이 좋습니다.


@ jfs : 어쨌든 와이어에서 다른 수십 가지 이상의 다른 인코딩이 여전히 존재한다면 왜 유니 코드가 있습니까? 전역 매핑은 그 자체로 어떤 용도로 사용됩니까?
Matthew Scharley

10
@Matthew Scharley : 잘못보고 있습니다. UNICODE는 모든 언어 (Klingon 포함)의 모든 문자를 UNIQUE ID (코드 점)에 매핑합니다 . 인코딩은 코드 포인트를 디스크 또는 네트워크를 통한 스트림으로 압축하는 방법 일뿐입니다. UTF는 "UNICODE Transport format"을 나타냅니다. 항상 UNICODE 코드 포인트를 21 비트 값으로 생각해야합니다. 다른 형식에 비해 장점은 모든 문자가 고유하게 식별되고 겹치지 않는다는 것입니다 (Latin-1, Latin-2 등과 달리).
Martin York

@Matthew Scharley 글로벌 매핑이 필요한 이유는 무엇입니까? 실제로 모든 사람은 과거에 자신의 매핑을 가졌습니다 (코드 페이지를 기억하십니까?). 나는 어리석은 예가 문제를 해결해 줄 것이라고 생각합니다. 사랑의 아이디어를 상상해보십시오. 다른 사람에게 어떻게 표현 하시겠습니까? 꽃을 줘? "사랑해"라고? 누구나 자신의 표현 방식이 있습니다. 사랑 (추상적 인 아이디어)은 코드 포인트와 같습니다. 그것을 표현하는 것은 인코딩과 같습니다. :)
jfs

4
유니 코드는 글로벌 알파벳입니다. UTF-x는 컴퓨터를 통해 전송되는 방식입니다. 전선을 통해 종이를 넣기가 어렵 기 때문입니다.
Mel

1
@Martin, Klingon은 실제로 만들지 않았습니다. Tengwar 나 Cirith도 톨킨의 엘프 혀를 쓰는 데 사용되지 않았습니다.
TRiG

9

UTF-7, UTF-8, UTF-16 및 UTF-32는 단순히 동일한 코딩 (코드 포인트) 문자 의 알고리즘 변환 형식입니다 . 그것들은 한 문자 체계 체계의 인코딩 입니다.

또한 256 자보다 큰 문자 세트를 처리하기위한 대부분의 이전 체계보다 알고리즘 적으로 앞뒤로 탐색하기가 더 쉽습니다.

이것은 일반적으로 국가에 따라 그리고 때로는 벤더에 따라 글리프의 목록과 다릅니다. 일본어만으로도 DOS / Windows 시스템에서 사용한 Shift-JIS라고하는 EUC-JP와 JIS의 코드 페이지 중심 변환은 말할 것도없이 JIS 만 변형 된 형태가있었습니다. (어느 정도까지는 알고리즘 변환이 있었지만 특히 간단하지는 않았으며 사용 가능한 문자에 공급 업체별로 차이가있었습니다.이를 몇 백 국가에 곱하고보다 정교한 글꼴 시스템의 점진적 진화 (그린 스크린 후) 시대), 그리고 당신은 진짜 악몽을 가졌습니다.

이러한 유니 코드 변환 형식이 필요한 이유는 무엇입니까? 많은 레거시 시스템은 ASCII 범위의 7 비트 문자 시퀀스를 가정했기 때문에 해당 시스템을 통해 데이터를 손상시키지 않고 안전하게 전달하는 7 비트 클린 솔루션이 필요했기 때문에 UTF-7이 필요했습니다. 그런 다음 8 비트 문자 집합을 처리 할 수있는 더 현대적인 시스템이 있었지만 null은 일반적으로 특별한 의미를 가지므로 UTF-16은 작동하지 않았습니다. 2 바이트는 첫 번째 화신으로 유니 코드의 기본 다국어 평면 전체를 인코딩 할 수 있으므로 UCS-2는 "유니 코드를 처음부터 알 수있는"시스템 (Windows NT 및 Java VM 등)에 적합한 접근 방식으로 보였습니다. 그 이상으로 확장하려면 추가 문자가 필요했습니다. 이는 유니 코드 표준에 의해 예약 된 21 비트 분량의 인코딩을 알고리즘 변환하여 대리 쌍을 탄생시켰다. UTF-16이 필요했습니다. 스토리지 효율성보다 문자 너비의 일관성이 중요한 응용 프로그램이 있다면 UTF-32 (UCS-4라고도 함)가 옵션이었습니다.

UTF-16은 처리하기에 원격으로 복잡한 유일한 요소이며이 변환의 영향을받는 작은 문자 범위와 선행 16 비트 시퀀스가 ​​후행과 완전히 다른 범위에 있다는 사실로 쉽게 완화됩니다. 16 비트 시퀀스. 이스케이프 시퀀스를 처리하기 위해 상태 머신 (JIS 및 EUC)이 필요하거나 보장 된 것을 발견 할 때까지 여러 문자를 뒤로 이동할 수있는 많은 초기 동아시아 인코딩에서 앞뒤로 이동하는 것보다 세상이 더 쉽습니다. 리드 바이트 (Shift-JIS) 만됩니다. UTF-16은 16 비트 시퀀스를 효율적으로 처리 할 수있는 시스템에서도 몇 가지 장점이있었습니다.

수십 (실제로 수백 가지)의 다른 인코딩을 거치지 않았거나 때로는 동일한 문서 (예전 MacOs 버전의 WorldScript와 같은)에서도 다른 인코딩으로 여러 언어를 지원하는 시스템을 구축하지 않았다면, 불필요한 복잡성으로 유니 코드 변환 형식. 그러나 이전 대안에 비해 복잡성이 크게 줄어 들었으며 각 형식은 실제 기술적 제약을 해결합니다. 또한 서로간에 효율적으로 변환 할 수있어 복잡한 조회 테이블이 필요하지 않습니다.


1
다양한 JIS 및 EUC 상태 머신은 실제로 불쾌하며 두 머신 사이에서 변환 작업을 수행하는 경우에는 두 배가됩니다. 유니 코드는이를 매우 단순화합니다. 유니 코드를 가진 유일한 큰 문제는 당신이 한 것입니다 가지고 문자로 바이트의 정지 생각에, 당신은 ASCII-사용 우월 주의자에게 당신을 작은 문자를-잘 살고!
Donal Fellows

6

유니 코드는 많은 다른 인코딩을 갖는 전체 문제를 해결하도록 설계되지 않았습니다.

유니 코드는 사용중인 코드 페이지에 따라 많은 다른 것을 나타내는 하나의 숫자 전체를 해결하도록 설계되었습니다. 숫자 0-127은 Ansi 코드 페이지에서 동일한 문자를 나타냅니다. ASCII 차트 또는 문자 집합이라고도합니다. 256자를 허용하는 Ansi 코드 페이지에서 숫자 128-255는 다른 코드 페이지에서 다른 문자를 나타냅니다.

예를 들어

  • 숫자 $ 57은 모든 코드 페이지에서 대문자 W를 나타내지 만
  • 숫자 $ EC는 코드 페이지 437 (미국)의 무한대 기호를 나타내지 만 코드 페이지 775 ( "발트 어)의"중간체 문자가있는 세 밀라 "
  • Cent Sign은 코드 페이지 437에서 $ 9B이지만 코드 페이지 775에서 96입니다.

유니 코드가 한 일은 이것을 뒤집어 놓는 것이 었습니다. 유니 코드에는 "재사용"이 없습니다. 각 숫자는 하나의 고유 한 문자를 나타냅니다. 유니 코드의 숫자 $ 00A2는 센트 기호이며 센트 기호는 유니 코드 정의에서 다른 곳에 나타나지 않습니다.

그렇다면 왜 그렇게 많은 유니 코드 인코딩이 있습니까? UTF-8, UTF-16 등과 같은 (본질적으로) 동일한 버전의 여러 버전조차도.

동일한 인코딩의 여러 버전이 없습니다. 동일한 유니 코드 문자 정의 맵의 다중 인코딩이 있으며, 유니 코드에 존재하는 다양한 언어 평면의 다양한 사용에 대한 스토리지 요구 사항을 관리하기 위해 "발명"되었습니다.

유니 코드는 4.294.967.295 개의 고유 문자를 정의합니다 (또는 정의 할 공간이 있음). 알고리즘 변환을 수행하지 않고 이들을 디스크 / 메모리 저장소에 매핑하려면 문자 당 4 바이트가 필요합니다. 모든 언어 비행기의 문자가있는 텍스트를 저장 해야하는 경우 UTF-32 (기본적으로 유니 코드 정의의 직선 1 문자-4 바이트 스토리지 인코딩)가 필요할 것입니다.

그러나 거의 모든 텍스트가 모든 언어 평면의 문자를 사용하는 경우는 거의 없습니다. 그리고 문자 당 4 바이트를 사용하는 것은 큰 낭비입니다. 특히 지구상의 대부분의 언어가 BMP (Basic Multi-lingual Plane) : 유니 코드 정의의 처음 65536 번호 내에 정의되어 있음을 고려할 때 특히 그렇습니다.

UTF-16이 등장한 곳입니다. BMP의 문자 만 사용하는 경우 UTF-16은 문자 당 2 바이트 만 사용하여 매우 효율적으로 저장합니다. BMP 외부의 문자에만 더 많은 바이트를 사용합니다. UTF-16LE (Little Endian)과 UTF-16BE (Big Endian)의 차이점은 실제로 숫자가 컴퓨터 메모리 내에서 표현되는 방식 ( A016 진수 $ A0 또는 $ 0A를 의미하는 바이트 패턴 )과 관련이 있습니다.

텍스트가 서유럽 언어의 대부분의 텍스트와 같이 훨씬 적은 수의 다른 문자를 사용하는 경우 텍스트의 저장 요구 사항을 더 제한해야합니다. 따라서 UTF-8은 단일 바이트를 사용하여 ASCII 차트에있는 문자 (처음 128 개 숫자)와 Ansi 문자 (다양한 코드 페이지의 두 번째 128 개 숫자)를 저장합니다. 이 "가장 많이 사용 된 문자"세트 이외의 문자에 대해서만 더 많은 바이트를 사용합니다.

요약하면 다음과 같습니다.

  • 유니 코드는 지구상의 모든 언어 (및 일부 Klingon 부팅) 문자와 일부 문자 (수학적, 음악 등)를 고유 번호로 매핑합니다.
  • 인코딩은 텍스트 내 문자의 "평균 사용량"을 고려할 때이 고유 문자 맵의 번호를 가능한 한 효율적으로 공간을 사용하여 텍스트를 저장하도록 정의 된 알고리즘입니다.

2
"숫자 0-127은 모든 코드 페이지에서 동일한 문자를 나타냅니다." -글쎄, 당신이 EBCDIC를 말하지 않는다면,이 경우 $57에는 W가 아닙니다
MSalters

@MSalters : 당신은 절대적으로 옳습니다. EBCDIC은 다릅니다 (다른 EBCDIC도 있습니다). 내 메인 프레임 시절이 너무 길어서 기억 나지 않았거나이 기억들을 너무 세고 억
눌렀습니다

"숫자 0-127은 모든 코드 페이지에서 동일한 문자를 나타냅니다." ASCII의 상위 집합이 아닌 BinarySignWriting과 같은 인코딩이 실제로 있습니다. 실제로 BinarySignWriting에는 ASCII 문자가 전혀 포함되지 않습니다.
TRiG

@TRiG : 그렇기 때문에 Ansi 코드 페이지에 대한 설명을 편집했습니다. 당신이 새로 고치기 전에 그 일을 했어야했는데 ...
Marjan Venema

예. 내 의견을 쓰는 동안 추가 의견과 게시물 업데이트가있었습니다. 여전히 BinarySignWriting은 흥미 롭습니다.
TRiG

2

유니 코드는 숫자와 문자 사이의 맵을 정의합니다. 그러나 수신자에게 번호를 보낼 때 해당 번호를 나타내는 방법을 정의해야합니다. 그것이 UTF의 목적입니다. 바이트 스트림에서 숫자를 나타내는 방법을 정의합니다.


2

UTF-32의 이론적 근거는 간단합니다. 이것은 유니 코드 코드 포인트를 가장 간단하게 표현한 것입니다. 그렇다면 UTF-32의 모든 것이 왜 그렇지 않습니까? 두 가지 주요 이유 :

하나는 크기 입니다. UTF-32는 모든 문자에 4 바이트가 필요합니다. 기본 다국어 환경에서 문자 만 사용하는 텍스트의 경우 UTF-16보다 두 배의 공간입니다. 영어 텍스트의 경우 US-ASCII보다 4 배 많은 공간입니다.

더 큰 이유는 이전 버전과의 호환성 입니다. "인코딩되지 않은"UTF-32 이외의 각 유니 코드 인코딩은 이전 표준과의 호환성을 위해 설계되었습니다.

  • UTF-8 : US-ASCII와의 호환성
  • UTF-16 : UCS-2와의 호환성 (BMP 이상으로 확장되기 전에 16 비트 유니 코드)
  • UTF-7 : 8 비트가 아닌 클린 메일 서버와의 호환성.
  • GB18030 : 중국어 용 GB2312 및 GBK 인코딩과의 호환성.
  • UTF-EBCDIC : EBCDIC의 기본 라틴 하위 집합과의 호환성

유니 코드는 많은 다른 인코딩을 사용하는 전체 문제를 해결하도록 설계되었다고 생각했습니다.

그렇습니다. 언어와 OS에 따라 수백 가지 의 다른 문자 인코딩 시스템을 처리하는 것보다 UTF-8, -16 및 -32 사이를 변환하는 것이 훨씬 쉽습니다 .


1

zip 파일은 파일을 훨씬 더 작게 (특히 텍스트) 압축 한 다음 원본 파일의 동일한 사본으로 압축 해제 할 수 있습니다.

압축하는 알고리즘이 실제로있는 여러 선택 가능한 서로 다른 특성을 가진 다른 알고리즘 : 저장 (비 압축), 수축 감소 (방식 1-4), 내파, 토큰 화, 수축, Deflate64, BZIP2, LZMA (EFS) WavPack, PPMD, 이론적으로 모든 것을 시도하고 최상의 결과를 선택할 수 있지만 일반적으로 Deflated를 사용하십시오.

UTF는 거의 같은 방식으로 작동합니다. 각각 다른 특성을 가진 여러 인코딩 알고리즘이 있지만 일반적으로 UTF-8은 다른 UTF 변형과 달리 광범위하게 지원되므로 7 비트 ASCII와 비트 호환되므로 쉽게 UTF-8을 선택할 수 있습니다. 일반적으로 ASCII의 8 비트 확장을 사용하는 대부분의 최신 컴퓨터 플랫폼에서 사용합니다.


ørn : zip 파일과의 차이점은 어떤 압축이 적용되는지 알려주는 헤더가 있다는 것입니다. 텍스트 파일로 우리는 여전히 우리를 추측해야합니까?
Matthew Scharley 1

정확히 알려주는 특별한 순서가 있습니다. ASCII와의 하위 호환성으로 인해 선택적입니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.