UTF-8

UTF-8
UTF-8
표준.유니코드 표준
분류유니코드 변환 포맷, 확장 ASCII, 가변 길이 인코딩
익스텐디드아스키
변환 / 인코딩ISO/IEC 10646 (유니코드)
선행후UTF-1

UTF-8은 전자통신에 사용되는 가변길이 문자 부호화 규격입니다. 유니코드 표준에 의해 정의된 이름은 유니코드 변환 형식 - 8비트에서 파생되었습니다.[1]

UTF-8은 1~4개의 1바이트(8비트) 코드 유닛을 사용하여 1,112,064개의[a] 유효한 유니코드 코드 포인트를 모두 인코딩할 수 있습니다. 더 자주 발생하는 경향이 있는 수치가 낮은 코드 포인트는 더 적은 바이트를 사용하여 인코딩됩니다. ASCII와의 하위 호환성을 위해 설계되었습니다. ASCII와 일대일 대응하는 유니코드의 첫 128자는 ASCII와 동일한 이진값을 가진 단일 바이트를 사용하여 인코딩되므로 유효한 ASCII 텍스트는 UTF-8 인코딩 유니코드도 유효합니다.

UTF-8은 부분 ASCII 호환성이 있는 제안된 가변 길이 인코딩인 UTF-1보다 우수한 대안으로 설계되었으며, 자체 동기화 및 슬래시와 같은 문자의 완전한 ASCII 호환성을 포함한 일부 기능이 부족했습니다. Ken ThompsonRob Pike는 1992년 9월 Plan 9 운영 체제를 위한 첫 번째 구현을 제작했습니다.[2][3] 이로 인해 X/OpenFSS-UTF에 대한 사양으로 채택되었으며,[4] 이 사양은 1993년[5] 1월 USENIX에서 처음으로 공식적으로 발표된 후 향후 인터넷 표준 작업을 위해 RFC 2277(BCP 18)[6]에서 IETF(Internet Engineering Task Force)에 의해 채택되었으며, 이전 RFC의 Latin-1과 같은 단일 바이트 문자 집합을 대체했습니다.

UTF-8은 어떤 대체 텍스트 인코딩보다 더 적은 국제화 문제를[7][8] 초래하며, 마이크로소프트 윈도우를 포함한 모든 현대 운영 체제JSON과 같은 표준에서 구현되었으며, 점점 더 그러하듯이 유니코드가 유일하게 허용되는 형태입니다.

UTF-8은 월드 와이드 웹(및 인터넷 기술)의 지배적인 인코딩으로, 2024년 기준으로 전체 웹 페이지의 98.2%, 상위 10,000 페이지의 99.0%, 많은 언어의 경우 최대 100%를 차지합니다.[9] 사실상 모든 국가와 언어가 웹에서 UTF-8 인코딩을 95% 이상 사용하고 있습니다.

명명

인코딩의 공식 이름은 UTF-8로 모든 유니코드 컨소시엄 문서에서 사용되는 철자입니다. 대부분의 표준은 공식적으로 대문자로 나열하지만 대소문자를 구분하지 않고 모든 작업을 수행합니다. utf-8 코드에 자주 사용됩니다.[citation needed]

일부 다른 철자법은 표준에서 허용할 수도 있습니다. 예를 들어, 웹 표준(CSS, HTML, XMLHTTP 헤더 포함)은 utf8(및 "유니코드"를 허용하지 않음)과 인코딩에 대한 많은 별칭을 명시적으로 허용합니다.[10] 예를 들어 "UTF 8"과 같은 공백이 있는 철자는 사용해서는 안 됩니다. 공식 인터넷 할당 번호 기관은 또한 거의 사용되지 않는 유일한 별칭으로 csUTF8을 나열합니다.[11]

Windows에서 UTF-8은 코드 페이지입니다. 65001[12] (즉,) CP_UTF8 소스코드로).

MySQL에서 UTF-8은 utf8mb4[13] (with) utf8mb3, 그리고 그 가명. utf8, 기본 다국어 평면[14] 문자에 대한 하위 인코딩입니다. HPCL에서 UTF-8의 Symbol-ID는 18N.[15]

Oracle Database(버전 9.0 이후)에서는 AL32UTF8[16] UTF-8을 의미합니다. 거의 사용되어서는 안 되는 UTF-8과 거의 동의어에 대해서는 CESU-8을 참조하십시오.

UTF-8-BOMUTF-8-NOBOM은 각각 BOM(바이트 순서 표시)을 포함하거나 포함하지 않는 텍스트 파일에 사용되기도 합니다.[citation needed] 특히 일본에서는 BOM이 없는 UTF-8 인코딩을 UTF-8N이라고 부르기도 합니다.[17][18]

인코딩

UTF-8은 코드 포인트의 값에 따라 1~4바이트 단위로 코드 포인트를 부호화합니다. 다음 표에서 x 문자는 코드 포인트의 비트로 대체됩니다.

코드 포인트 ↔ UTF-8 변환
첫 번째 코드 포인트 마지막 코드 포인트 바이트 1 바이트 2 바이트 3 바이트 4
U+0000 U+007F 0xxxxxxxxxx
U+0080 U+07FF 110xxxxxxx 10xxxxxxxxxx
U+0800 U+FFFF 1110xxxxxx 10xxxxxxxxxx 10xxxxxxxxxx
U+010000 [b]U+10FFF 11110xxx 10xxxxxxxxxx 10xxxxxxxxxx 10xxxxxxxxxx

처음 128개의 코드 포인트(ASCII)는 1바이트가 필요합니다. 다음 1,920개의 코드 포인트는 인코딩하기 위해 2바이트가 필요하며, 이는 거의 모든 라틴 문자 알파벳의 나머지 부분을 포함하며, 또한 IPA 확장, 그리스어, 키릴 문자, 콥트 문자, 아르메니아어, 히브리어, 아랍어, 시리아어, 타나 문자, N'Ko 문자, 결합 등도 포함합니다. 기본 다국어 평면(BMP)의 나머지 61,440개 코드 포인트에는 대부분의 중국어, 일본어 한국어 문자를 포함하여 3바이트가 필요합니다. 유니코드의 다른 평면에 있는 1,048,576개의 코드 포인트에 4바이트가 필요한데, 이는 이모지(그림 기호), 덜 흔한 CJK 문자, 다양한 역사적 스크립트, 수학적 기호를 포함합니다.

전체 그래픽 문자는 하나 이상의 코드 포인트로 만들어지기 때문에 4바이트 이상이 소요될 수 있습니다. 예를 들어, 국기 문자는 BMP 외부에서 "한 쌍의 유니코드 스칼라 값으로 구성"되기 때문에 8바이트가 소요됩니다.[19][c]

다음 예제에서 빨간색, 녹색 및 파란색 숫자는 코드 포인트의 비트가 UTF-8 바이트 사이에 분배되는 방식을 나타냅니다. UTF-8 인코딩 과정에 의해 추가된 비트는 검은색으로 표시됩니다.
  1. 유로 부호 €의 유니코드 코드 포인트는 U+20AC입니다.
  2. 이 코드 포인트는 U+0800과 U+FFFFF 사이에 있기 때문에 인코딩하는 데 3바이트가 필요합니다.
  3. 16진수 20AC는 이진 00100000101100입니다. 3바이트 인코딩에는 코드 포인트에서 정확히 16비트가 필요하기 때문에 두 개의 선행 0이 추가됩니다.
  4. 인코딩 길이가 3바이트이므로 선두 바이트는 3개의 1로 시작하고 0(1110...)으로 시작합니다.
  5. 코드 포인트의 가장 중요한 4비트는 이 바이트(11100010)의 나머지 하위 4비트에 저장되며, 코드 포인트의 12비트는 아직 인코딩되지 않았습니다(...0000101100).
  6. 모든 연속 바이트는 코드 포인트에서 정확히 6비트를 포함합니다. 따라서 코드 포인트의 다음 6비트는 다음 바이트의 낮은 순서 6비트에 저장되고, 10비트는 높은 순서 2비트에 저장되어 연속 바이트(so 10000010)로 표시됩니다.
  7. 마지막으로 코드 포인트의 마지막 6비트는 최종 바이트의 하위 6비트에 저장되고, 다시 10비트는 상위 2비트에 저장됩니다(10101100).

3바이트 11100010 10000010 10101100E282 AC와 같이 16진수로 더 간결하게 작성할 수 있습니다.

다음 표에는 이 변환과 UTF-8의 길이가 다른 변환이 요약되어 있습니다.

UTF-8 부호화 과정
성격 이진 코드 포인트 바이너리 UTF-8 육각 UTF-8
$ U+0024 010 0100 00100100 24
£ U+00A3 000 1010 0011 11000010 10100011 C2 A3
И U+0418 100 0001 1000 11010000 10011000 D0 98
ह (데바나가리 문자 HA) U+0939 0000 1001 0011 1001 11100000 10100100 10111001 E0 A4 B9
U+20AC 0010 0000 1010 1100 11100010 10000010 10101100 E2 82 교류
U+D55C 1101 0101 0101 1100 11101101 10010101 10011100 ED 95 9C
𐍈 U+10348 0 0001 0000 0011 0100 1000 11110000 10010000 10001101 10001000 F0 90 8D 88
Suppl Private Use Area B U+1096B3 1 0000 1001 0110 1011 0011 11110100 10001001 10011010 10110011 F4 89 9A B3

베트남 어구인 므ì흐누이 티 ế 응 비 ệ(𨉟呐㗂越, "I speak Vietnam")는 다음과 같이 인코딩됩니다.

성격 M ì n h n ó i t i ế n g V i t
코드 포인트 4D EC 6E 68 20 6E F3 69 20 74 69 1EBF 6E 67 20 56 69 1EC7 74
육각 UTF-8 C3 교류 C3 B3 E1 BA BF E1 BB 87
성격 𨉟
코드 포인트 2825F 5450 35C2 8D8A
육각 UTF-8 F0 A8 89 9F E5 91 90 E3 97 82 E8 B6 8A

코드페이지 레이아웃

다음 표는 코드 페이지 형식의 UTF-8 코드 유닛(개별 바이트 또는 옥텟) 사용을 요약한 것입니다. 위쪽 절반은 단일 바이트 코드에서만 사용되는 바이트이므로 일반 코드 페이지처럼 보입니다. 아래쪽 절반은 연속 바이트 및 선행 바이트용이며 아래 범례에서 자세히 설명합니다.

UTF-8
0 1 2 3 4 5 6 7 8 9 A B C D E F
0x NUL SOH STX ETX EOT ENQ ACK BS HT LF VT FF CR 그렇게 SI
1배 DLE DC1 DC2 DC3 DC4 NAK SYN ETB 할 수 있다 EM 후보선수 ESC FS GS RS 미국
2배 SP ! " # $ % & ' ( ) * + , - . /
3배 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
4배 @ A B C D E F G H I J K L M N O
5배 P Q R S T U V W X Y Z [ \ ] ^ _
6배 ` a b c d e f g h i j k l m n o
7배 p q r s t u v w x y z { } ~ DEL
8배 +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F
9x +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +1A +1B +1C +1D +1E +1F
악스 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +2A +2B +2C +2D +2E +2F
Bx +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +3A +3B +3C +3D +3E +3F
Cx 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
Dx 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
Fx 4 4 4 4 4 4 4 4 5 5 5 5 6 6
7비트(단일 바이트) 코드 포인트. 연속 바이트가 뒤따르지 않아야 합니다.[20]
연속 바이트입니다.[21] 셀은 그들이 추가하는 6비트의 값을 16진수로 보여줍니다.[d]
여러 바이트 시퀀스의 선두 바이트 뒤에는 정확히 N-1 연속 바이트가 따라야 합니다.[22] 툴팁은 코드 포인트 범위와 이 바이트로 시작하는 시퀀스로 인코딩된 유니코드 블록을 보여줍니다.
연속 바이트의 모든 배열이 유효하지 않은 선두 바이트입니다. E0F0은 긴 인코딩에서 시작할 수 있습니다. F4는 U+10FFF보다 큰 코드 포인트를 시작할 수 있습니다. ED는 U+D800–U+DFFF 범위의 코드 포인트를 시작할 수 있으며, 이 코드 포인트는 유효하지 않은 UTF-16 대리 하프입니다.[23]
올바른 UTF-8 시퀀스에 나타나지 마십시오. C0C1은 1바이트 문자의 "overlong" 인코딩에만 사용할 수 있습니다.[24] F5~FD는 U+10FFF보다 큰 코드 포인트만 인코딩할 수 있는 4바이트 이상의 시퀀스의 선두 바이트입니다.[23] FEFF는 어떤 의미도 부여되지 않았습니다.[25]

오버롱 인코딩

원칙적으로 코드 포인트에 선두 0을 추가하여 인코딩의 바이트 수를 부풀리는 것이 가능합니다. 위의 예제에서 나온 유로 부호 €를 3바이트가 아닌 4바이트로 인코딩하기 위해서21비트 길이가 될 때까지 선두 0으로 패딩하여 11110000001000010000100001000010000100001000010010000100001000010000100001000010000100001000010000100001000010000100001000010000100001000010000100001000010000100001000010000100001000010000100001000010000001000000100000010000000010000001000000001000000001000000100 이것을 오버롱 인코딩이라고 합니다.

이 표준은 코드 포인트의 올바른 인코딩이 코드 포인트의 상당한 비트를 유지하는 데 필요한 최소 바이트 수만 사용한다고 지정합니다.[citation needed] 더 긴 인코딩은 overlong이라고 불리며 코드 포인트의 유효한 UTF-8 표현이 아닙니다. 이 규칙은 코드 포인트와 유효한 인코딩 사이에 일대일 대응 관계를 유지하므로 각 코드 포인트에 고유한 유효한 인코딩이 있습니다. 이를 통해 문자열 비교 및 검색이 잘 정의됩니다.

잘못된 시퀀스 및 오류 처리

모든 바이트 시퀀스가 유효한 것은 아닙니다. UTF-8 디코더는 다음을 위해 준비되어야 합니다.

  • 유효하지 않은 바이트
  • 예상치 못한 연속 바이트
  • 문자가 끝나기 전의 비연속 바이트
  • 문자가 끝나기 전에 끝나는 문자열(단순 문자열 잘라내기에서 발생할 수 있음)
  • 지나치게 긴 부호화
  • 유효하지 않은 코드 포인트로 디코딩하는 시퀀스

많은 최초의 UTF-8 디코더들은 잘못된 비트들을 무시하고 너무 긴 결과들을 받아들이면서 이러한 것들을 디코딩할 것입니다. 잘못 만든 UTF-8은 생략하거나 NUL, 슬래시 또는 따옴표와 같은 ASCII 문자를 만들 수 있습니다. 잘못된 UTF-8은 Microsoft의 IIS 웹 서버[26] 및 Apache의 Tomcat 서블릿 컨테이너를 포함한 유명 제품에서 보안 검증을 우회하는 데 사용되었습니다.[27] RFC 3629는 "복호화 알고리즘의 구현은 유효하지 않은 시퀀스를 디코딩하는 것으로부터 보호해야 합니다"라고 기술합니다.[23] 유니코드 표준에는 디코더가 다음을 수행해야 합니다.

"... 잘못된 형식의 코드 단위 시퀀스를 오류 조건으로 취급합니다. 이를 통해 잘못된 형식의 코드 단위 시퀀스를 해석하거나 방출하지 않을 수 있습니다."

RFC 3629(2003년 11월) 이후, UTF-16(U+D800 ~ U+DFFF)에 의해 사용되는 높은 대리 반값과 낮은 대리 반값(U+10FFF 이후의 값) 및 UTF-16에 의해 인코딩될 수 없는 코드 포인트(U+10FFF 이후의 값)는 합법적인 유니코드 값이 아니며, 이들의 UTF-8 인코딩은 유효하지 않은 바이트 시퀀스로 처리되어야 합니다. 쌍을 이루지 않은 대리 반쪽을 해독하지 않으면 잘못된 UTF-16(예: Windows 파일 이름 또는 대리자 간에 분할된 UTF-16)을 UTF-8로 저장하는 것이 불가능하지만 [e]WTF-8에서는 가능합니다.

디코더의 일부 구현은 오류에 대한 예외를 적용합니다.[29] 그렇지 않으면 무해한 오류(예: "해당 파일 없음" 오류)가 서비스 거부로 전환될 수 있다는 단점이 있습니다. 예를 들어 Python 3.0의 초기 버전은 명령줄 또는 환경 변수에 잘못된 UTF-8이 포함된 경우 즉시 종료됩니다.[30]

유니코드 6([31]2010년 10월)부터 표준(제3장)은 오류가 1바이트 길이이거나 허용되지 않는 첫 번째 바이트 전에 끝나는 "베스트 프랙티스"를 권장했습니다. 이러한 디코더 E1,A0,C0는 2개의 오류(첫 번째 오류는 2바이트)입니다. 즉, 오류의 길이는 3바이트 이하이며 유효한 문자의 시작을 포함하지 않으며 21952개다양한 오류가 있을 수 있습니다.[f] 표준에서는 또한 각 오류를 대체 문자 "�"(U+FFFD)로 교체할 것을 권장합니다.

이러한 권장 사항은 자주 지켜지지 않습니다. 각 바이트를 오류로 간주하는 것이 일반적이며, 이 경우 E1,A0,C03개의 오류(각각 1바이트 길이)입니다. 이는 128개의 다른 오류만 있음을 의미하며, 디코딩을 "무손실"로 만들기 위해 128개의 다른 문자로 대체하는 것도 일반적입니다.[32]

바이트오더마크

유니코드 바이트 순서 표시(BOM, U+FEFF, 엄밀히 말하면 U+FEFF ZERO WIDTH NO-BREAK SPACE 문자)가 UTF-8 파일의 시작 부분에 있는 경우 처음 세 바이트는 0xEF, 0xBB, 0xBF가 됩니다.

유니코드 표준은 UTF-8에 BOM을 사용할 것을 요구하지도, 권장하지도 않지만, 다른 인코딩에서 트랜스코딩된 파일이 시작될 때 발생할 수 있음을 경고합니다.[33] UTF-8을 사용하여 인코딩된 ASCII 텍스트는 ASCII와 하위 호환되지만 유니코드 표준 권장 사항이 무시되고 BOM이 추가되는 경우에는 그렇지 않습니다. BOM은 준비되지 않은 소프트웨어를 혼동할 수 있습니다. 예를 들어 ASC가 아닌 것을 허용하는 프로그래밍 언어와 같이 UTF-8을 수용할 수 있습니다.문자열 리터럴 단위의 II 바이트이지만 파일 시작 부분에는 없습니다. 그럼에도 불구하고 UTF-8을 작성할 때 항상 BOM을 삽입하고 첫 번째 문자가 BOM이 아니면(또는 파일에 ASCII만 포함된 경우) UTF-8의 올바른 해석을 거부하는 소프트웨어가 있었고 여전히 존재합니다.[34]

입양

2010년 이후 가장 인기 있는 웹사이트 1,000만 곳에 선정된 캐릭터 세트
구글이 기록한 2001년부터 2012년까지 웹에서 주요 인코딩을 사용한 결과,[35] 2008년에는 UTF-8이 다른 모든 인코딩을 추월했고, 2012년에는 웹의 60% 이상을 추월했습니다(이후 100%에 근접했습니다). UTF-8은 유니코드의 (명시적으로) 유일한 인코딩이며, 나머지는 유니코드의 하위 집합만을 제공합니다. ASCII 전용 그림은 선언된 헤더에 관계없이 ASCII 문자만 포함하는 모든 웹 페이지를 포함합니다.

UTF-8은 2008년부터 월드 와이드 웹의 가장 일반적인 인코딩이었습니다.[36] UTF-8은 2024년 2월 현재 조사 대상 웹사이트의 98.2%가 사용하고 있습니다.[9][g] 비록 많은 페이지들이 내용을 표시하기 위해 ASCII 문자들만을 사용하지만, 매우 적은 수의 웹사이트들이 그것들의 인코딩을 UTF-8 대신 ASCII로만 선언합니다.[37] 추적되는 언어들 중 50% 이상이 100% UTF-8을 사용합니다.

많은 표준들이 UTF-8만 지원하는데, 예를 들어 JSON 교환은 그것을 요구한다(바이트 순서 표시(BOM)).[38] UTF-8은 또한 HTML과 DOM 사양에 대한 WHATWG의 권장 사항이기도 합니다. 또한 "UTF-8 인코딩은 유니코드의 상호 교환에 가장 적합한 인코딩"[8]이라고 명시하며 인터넷 메일 컨소시엄은 모든 전자 메일 프로그램이 UTF-8을 사용하여 메일을 표시하고 만들 수 있도록 권장합니다.[39][40] 월드 와이드 컨소시엄은 XML과 HTML의 기본 인코딩으로 UTF-8을 권장합니다(또한 UTF-8을 사용할 뿐만 아니라 메타데이터에서도 선언합니다). "모든 문자가 ASCII 범위에 있을 때에도... UTF-8이 아닌 인코딩을 사용하면 예상치 못한 결과가 발생할 수 있습니다."[41]

많은 소프트웨어들이 UTF-8을 읽고 쓸 수 있는 능력을 가지고 있습니다. 그러나 그것은 사용자가 일반적인 설정으로부터 옵션들을 바꾸도록 요구할 수도 있고, 파일을 읽기 위해 첫 문자로서 BOM (바이트 순서 표시)을 요구할 수도 있습니다. UTF-8을 지원하는 소프트웨어의 예로는 Microsoft Word,[42][43][44] Microsoft Excel(2016 이상),[45][46] Google Drive, LibreOffice 및 대부분의 데이터베이스가 있습니다.

그러나 로컬 텍스트 파일의 경우 UTF-8 사용이 덜 일반적이며 레거시 단일 바이트(및 몇 개의 CJK 다중 바이트) 인코딩이 여전히 사용되고 있습니다. 이는 파일의 첫 번째 바이트가 BOM(바이트 순서 표시)을 인코딩하지 않는 한 UTF-8을 읽기를 거부하는 구식 텍스트 편집기 때문입니다.[47]

일부 최신 소프트웨어는 UTF-8만 읽고 쓸 수 있습니다(또는 최소한 BOM이 필요하지 않음).[48]Windows 메모장은 현재 지원되는 모든 버전의 Windows에서 기본적으로 BOM 없이 UTF-8을 작성하며 대부분의 다른 텍스트 편집기와 일치합니다.[49] 윈도우 11의 일부 시스템 파일은 BOM이 필요하지 않은 UTF-8이[50] 필요하며, macOS와 Linux의 거의 모든 파일은 BOM이 없는 UTF-8이 필요합니다.[citation needed]자바 18은 UTF-8로 파일을 읽고 쓰는 것을 기본으로 하며,[51] 이전 버전(예: LTS 버전)에서는 NIO API만 변경되었습니다. Ruby 3.0[52][53] 및 R 4.2.2를 포함한 많은 다른 프로그래밍 언어들은 I/O를 위해 기본값을 UTF-8로 설정합니다.[54] 현재 지원되는 모든 버전의 파이썬은 윈도우에서조차 I/O용 UTF-8을 지원합니다. open() 함수[55]), 그리고 모든 플랫폼에서 UTF-8 I/O를 Python 3.15의 기본값으로 만들 계획이 존재합니다.[56][57]C++23은 유일한 휴대용 소스 코드 파일 형식으로 UTF-8을 채택하고 있습니다(놀랍게도 이전에는 없었습니다).[58]

메모리에서 UTF-8의 사용량은 다른 영역보다 훨씬 적으며, 대신 UTF-16이 많이 사용됩니다. 이것은 특히 윈도우에서 발생하지만, 자바스크립트인 파이썬에서도 발생합니다. {efn 파이썬은 "유니코드"라고 부르는 것에 여러 인코딩을 사용하지만, 이 인코딩들 중 어떤 것도 UTF-8이 아닙니다. 파이썬 2와 초기 버전 3은 윈도우에서 UTF-16을 사용했고 유닉스에서 UTF-32를 사용했습니다. 파이썬 3의 최근 구현에서는 필요한 최대 코드 포인트에 따라 ISO-8859-1, UCS-2 및 UTF-32의 세 가지 고정 길이 인코딩을 사용합니다.[h] Qt 및 기타 많은 크로스 플랫폼 소프트웨어 라이브러리. Windows API와의 호환성이 그 주된 이유입니다. 처음에는 BMP를 직접 인덱싱하면 속도가 향상될 것이라는 믿음 때문에 이러한 선택이 이루어졌습니다. UTF-8에 있는 외부 텍스트로 번역하면 소프트웨어 속도가 느려지고, 다른 코드 조각이 동일한 번역을 수행하지 않을 때 버그가 발생합니다.

역호환성은 16비트 인코딩 대신 UTF-8을 사용하도록 코드를 변경하는 데 심각한 장애가 되지만, 이러한 일이 발생하고 있습니다. Go,[60] Julia, Rust, Swift 5 [i] PyPy[62] 기본 문자열 프리미티브는 모든 경우에 내부적으로 UTF-8을 사용하는 반면, Python 3.3 이후 Python은 일부 경우에 내부적으로 UTF-8을 사용합니다(Python C API 확장용).[59][63] 미래 버전의 Python은 기본적으로 문자열을 UTF-8로 저장할 계획이며,[j][65] 최신 버전의 Microsoft Visual Studio는 내부적으로 UTF-8을 사용합니다.[66] 마이크로소프트의 SQL Server 2019는 UTF-8에 대한 지원을 추가했으며, 이를 사용하면 35%의 속도 향상과 "스토리지 요구사항을 거의 50% 절감"할 수 있습니다.[k]

현재 지원되는 모든 윈도우 버전은 어떤 방식으로든 (Xbox를 포함하여) UTF-8을 지원합니다.[7] 2019년 5월 현재, 마이크로소프트는 UTF-16만을 추천하던 기존의 입장을 뒤집었고, UTF-8을 윈도우 API의 "코드 페이지"로 설정할 수 있는 기능이 도입되었으며, 마이크로소프트는 프로그래머들에게 UTF-8을 사용할 을 권장하고 있으며,[l] 심지어 "UTF-16 [...]은 윈도우가 여러 플랫폼을 대상으로 하는 코드에 부여하는 고유한 부담"이라고 언급하고 있습니다.[m]

역사

국제표준화기구(ISO)는 1989년에 보편적인 멀티바이트 문자 집합을 구성하기 시작했습니다. ISO 10646 표준 초안에는 32비트 코드 포인트의 바이트 스트림 인코딩을 제공하는 UTF-1이라는 비필수 부속서가 포함되어 있습니다. 이 인코딩은 다른 문제들 중에서도 성능적인 이유로 만족스럽지 못했고, 아마도 가장 큰 문제는 ASCII와 ASCII가 아닌 것 사이에 명확한 구분이 없었다는 것입니다.II: 새로운 UTF-1 도구는 ASCII 인코딩 텍스트와 하위 호환되지만, UTF-1 인코딩 텍스트는 ASCII(또는 확장 ASCII)를 기대하는 기존 코드를 혼동할 수 있습니다. 예를 들어, '/'의 경우 0x2F와 같이 ASCII의 다른 의미를 갖는 연속 바이트를 포함할 수 있기 때문입니다. 그리고 이 예는 대체품의 이름과 소개 글에 반영되어 있습니다. 아래 표는 부속서의 텍스트 설명에서 파생되었습니다.

UTF-1
첫 번째 코드 포인트 마지막 코드 포인트 바이트 1 바이트 2 바이트 3 바이트 4 바이트 5
U+0000 U+009F 00~9F
U+00A0 U+00FF A0 A0–FF
U+0100 U+4015 A1~F5 21-7E, A0-FF
U+4016 U+38E2D F6–FB 21-7E, A0-FF 21-7E, A0-FF
U+38E2E U+7FFFFFF FC-FF 21-7E, A0-FF 21-7E, A0-FF 21-7E, A0-FF 21-7E, A0-FF

1992년 7월 X/오픈위원회 XoJIG는 더 나은 인코딩을 찾고 있었습니다. 유닉스 시스템 연구소의 데이브 프로서는 더 빠른 구현 특성을 가진 제안서를 제출했고, 7비트 ASCII 문자는 그 자체만을 나타낼 뿐이며, 모든 멀티 바이트 시퀀스는 높은 비트가 설정된 바이트만 포함할 것이라는 개선점을 소개했습니다. FSS-UTF(File System Safe UCS Transformation Format)라는 이름과 이 제안의 대부분의 텍스트는 나중에 최종 사양에 보존되었습니다.[69][70][71][72]

금감원-UTF

FSS-UTF 제안서 (1992)
첫 번째 코드 포인트 마지막 코드 포인트 바이트 1 바이트 2 바이트 3 바이트 4 바이트 5
U+0000 U+007F 0xxxxxxxxxx
U+0080 U+207F 10xxxxxxxxxx 1xxxxxxxxxx
U+2080 U+8207F 110xxxxxxx 1xxxxxxxxxx 1xxxxxxxxxx
U+82080 U+208207F 1110xxxxxx 1xxxxxxxxxx 1xxxxxxxxxx 1xxxxxxxxxx
U+2082080 U+7FFFFFF 11110xxx 1xxxxxxxxxx 1xxxxxxxxxx 1xxxxxxxxxx 1xxxxxxxxxx

1992년 8월, 이 제안은 IBM X/Open 담당자가 이해 관계자에게 배포했습니다. 벨 연구소플랜 9 운영 체제 그룹의 켄 톰슨(Ken Thompson)이 수정한 결과, 이전 제안보다 비트 효율성이 다소 떨어지는 대신 독자가 어디서나 시작하고 문자 경계를 즉시 감지할 수 있도록 자체 동기화가 가능해졌습니다. 또한 편향의 사용을 포기하고 가능한 한 가장 짧은 인코딩만 허용한다는 규칙을 추가했습니다. 컴팩트성에서 추가적인 손실은 상대적으로 미미하지만 독자들은 이제 신뢰성 및 특히 보안 문제를 피하기 위해 잘못된 인코딩을 찾아야 합니다. 톰프슨의 디자인은 1992년 9월 2일 롭 파이크(Rob Pike)와 함께 뉴저지(New Jersey) 식당의 플라세매트(Placemat)에서 윤곽이 드러났습니다. 그 다음 날 Pike와 Thompson은 이를 구현하고 Plan 9를 업데이트하여 전체적으로 사용하도록 한 다음 성공을 X/Open에 전달했으며, 이를 FSS-UTF의 사양으로 받아들였습니다.[71]

FSS-UTF (1992) / UTF-8 (1993)[2]
첫 번째 코드 포인트 마지막 코드 포인트 바이트 1 바이트 2 바이트 3 바이트 4 바이트 5 바이트 6
U+0000 U+007F 0xxxxxxxxxx
U+0080 U+07FF 110xxxxxxx 10xxxxxxxxxx
U+0800 U+FFFF 1110xxxxxx 10xxxxxxxxxx 10xxxxxxxxxx
U+10000 U+1FFFF 11110xxx 10xxxxxxxxxx 10xxxxxxxxxx 10xxxxxxxxxx
U+20000 U+3FFFF 111110xx 10xxxxxxxxxx 10xxxxxxxxxx 10xxxxxxxxxx 10xxxxxxxxxx
U+4000000 U+7FFFFFF 1111110x 10xxxxxxxxxx 10xxxxxxxxxx 10xxxxxxxxxx 10xxxxxxxxxx 10xxxxxxxxxx

UTF-8은 1993년 1월 25일부터 29일까지 샌디에이고에서 열린 USENIX 회의에서 처음으로 공식 발표되었습니다. 1998년 1월, 인터넷 엔지니어링 태스크 포스는 향후 인터넷 표준 작업을 위해 RFC 2277(BCP18)의 문자 집합 및 언어에 관한 정책에서 UTF-8을 채택했으며, 이전 RFC의 라틴-1과 같은 단일 바이트 문자 집합을 대체했습니다.[6]

2003년 11월, UTF-8은 다음과 같이 제한되었습니다. UTF-16 문자 인코딩의 제약 조건과 일치하도록 RFC3629: 3바이트 시퀀스 중 3% 이상 제거된 상위 및 하위 대리 문자에 해당하는 코드 포인트를 명시적으로 금지하고, U+10FFF로 끝나는 것은 4바이트 시퀀스 중 48% 이상 제거되고, 5바이트 및 6바이트 시퀀스 모두 제거됨.

표준

다양한 표준 문서에 UTF-8의 현재 정의가 몇 가지 있습니다.

  • 표준 인터넷 프로토콜 요소로서 UTF-8을 설정하는 RFC 3629 / STD 63 (2003)
  • RFC 5198 네트워크 교환을 위한 UTF-8 NFC 정의 (2008)
  • ISO/IEC 10646:2014 §9.1 (2014)[73]
  • 유니코드 표준, 버전 15.0.0 (2022)[74]

이들은 다음과 같은 오래된 저작물에 주어진 정의를 대체합니다.

  • 유니코드 표준, 버전 2.0, 부록 A (1996)
  • ISO/IEC 10646-1: 1993 개정 2 / 부속서 R(1996)
  • RFC 2044 (1996)
  • RFC 2279 (1998)
  • 유니코드 표준, 버전 3.0, § 2.3 (2000) + 코리젠덤 #1 : UTF-8 최단 형태 (2000)
  • 유니코드 표준부속서 #27: 유니코드 3.1 (2001)[75]
  • 유니코드 표준, 버전 5.0 (2006)[76]
  • 유니코드 표준, 버전 6.0 (2010)[77]

이들은 일반적인 메커니즘에서 모두 동일하며, 주요 차이점은 허용된 코드 포인트 값 범위 및 잘못된 입력의 안전한 처리와 같은 문제에 있습니다.

다른 인코딩과의 비교

이 인코딩의 몇 가지 중요한 기능은 다음과 같습니다.

  • 하위 호환성: ASCII와의 하위 호환성과 ASCII 인코딩 텍스트를 처리하도록 설계된 엄청난 양의 소프트웨어가 UTF-8 설계의 주요 원동력이었습니다. UTF-8에서는 0에서 127 범위의 값을 가진 단일 바이트가 ASCII 범위의 유니코드 코드 포인트에 직접 매핑됩니다. 이 범위의 단일 바이트는 ASCII에서와 같이 문자를 나타냅니다. 또한 7비트 바이트(가장 중요한 비트가 0인 바이트)는 멀티바이트 시퀀스에 나타나지 않으며, 유효한 멀티바이트 시퀀스는 ASCII 코드 포인트로 디코딩되지 않습니다. 7비트 바이트 시퀀스는 유효한 ASCII 및 유효한 UTF-8이며, 두 가지 해석 모두에서 동일한 문자 시퀀스를 나타냅니다. 따라서 UTF-8 스트림의 7비트 바이트는 스트림의 모든 문자와 ASCII 문자만 나타냅니다. 따라서 포맷 및 제어 목적으로 ASCII 문자를 사용하는 많은 텍스트 프로세서, 파서, 프로토콜, 파일 형식, 텍스트 표시 프로그램 등은 다중 바이트 시퀀스를 디코딩하지 않고 UTF-8 바이트 스트림을 단일 바이트 문자 시퀀스로 취급하여 의도한 대로 계속 작동할 것입니다. 펑처링, 공백 및 제어 문자와 같이 처리가 돌아가는 ASCII 문자는 절대 멀티바이트 시퀀스로 인코딩되지 않습니다. 따라서 이러한 프로세서는 다중 바이트 시퀀스를 디코딩하지 않고 단순히 무시하거나 통과하는 것이 안전합니다. 예를 들어, ASCII 공백은 UTF-8 스트림을 단어로 토큰화하는 데 사용될 수 있고, ASCII 라인 피드는 UTF-8 스트림을 라인으로 분할하는 데 사용될 수 있으며, ASCII NUL 문자는 UTF-8 인코딩된 데이터를 널 종단 문자열로 분할하는 데 사용될 수 있습니다. 마찬가지로 "printf"와 같은 라이브러리 함수에서 사용하는 많은 형식 문자열은 UTF-8 인코딩된 입력 인수를 올바르게 처리합니다.
  • 폴백 및 자동 탐지: 가능한 바이트 문자열의 작은 부분 집합만이 유효한 UTF-8 문자열입니다. 여러 바이트가 나타날 수 없고, 높은 비트 집합을 가진 바이트는 단독일 수 없으며, 추가 요구 사항은 확장된 ASCII에서 읽을 수 있는 텍스트가 유효한 UTF-8일 가능성이 매우 낮다는 것을 의미합니다. UTF-8이 인기를 끄는 이유는 UTF-8이 하위 호환성을 제공하기 때문입니다. 따라서 확장 ASCII를 입력으로 잘못 수신한 UTF-8 프로세서는 매우 높은 신뢰성으로 이를 "자동 감지"할 수 있습니다. UTF-8 스트림은 단순히 오류를 포함하여 자동 탐지 체계가 잘못된 양성을 생성할 수 있지만, 자동 탐지는 대부분의 경우, 특히 긴 텍스트에서 성공적이며 널리 사용됩니다. 또한 UTF-8의 오류가 감지될 때 레거시 인코딩에 적합한 코드 포인트를 사용하여 8비트 바이트를 "폴백"하거나 대체하여 UTF-8과 레거시 인코딩이 동일한 파일에서 연결되더라도 복구가 가능합니다.
  • 접두사 코드: 첫 번째 바이트는 시퀀스의 바이트 수를 나타냅니다. 스트림에서 읽기를 하면 먼저 다음 시퀀스의 첫 번째 바이트나 스트림 종료 표시를 기다릴 필요 없이 완전히 수신된 각 시퀀스를 즉시 디코딩할 수 있습니다. 다중 바이트 시퀀스의 길이는 단순히 선두 바이트의 고차 1의 개수이기 때문에 인간이 쉽게 결정합니다. 스트림이 시퀀스 중간에 끝나면 잘못된 문자가 디코딩되지 않습니다.
  • 자체 동기화: 선행 바이트와 연속 바이트는 값을 공유하지 않습니다(연속 바이트는 비트 10으로 시작하지만 단일 바이트는 0으로 시작하고 긴 리드 바이트는 11로 시작합니다). 이는 검색이 다른 문자의 중간에서 시작하는 한 문자에 대한 시퀀스를 실수로 찾지 않음을 의미합니다. 이는 또한 최대 3바이트를 백업하여 선두 바이트를 찾음으로써 임의의 위치에서 문자의 시작을 찾을 수 있음을 의미합니다. 스트림이 시퀀스 중간에 시작하면 잘못된 문자가 디코딩되지 않고 더 짧은 시퀀스가 더 긴 시퀀스 내부에 나타나지 않습니다.
  • 정렬 순서: 선두 바이트의 선택된 값은 해당 바이트 시퀀스를 정렬하여 UTF-8 문자열 목록을 코드 포인트 순서로 정렬할 수 있음을 의미합니다.

싱글바이트

  • UTF-8은 모든 유니코드 문자를 인코딩할 수 있으므로 "코드 페이지"를 파악하고 설정하거나 사용 중인 문자 집합을 표시할 필요가 없으며 동시에 여러 스크립트로 출력할 수 있습니다. 많은 스크립트에서 단일 바이트 인코딩이 하나 이상 사용되었기 때문에 스크립트를 아는 것조차 올바르게 표시하기에는 정보가 부족했습니다.
  • 바이트 0xFE 및 0xFF가 나타나지 않으므로 유효한 UTF-8 스트림이 UTF-16 바이트 순서 표시(BOM)와 일치하지 않으므로 혼동할 수 없습니다. 또한 0xFF(0377)가 없기 때문에 Telnet(및 FTP 제어 연결)에서 이 바이트를 벗어날 필요가 없습니다.
  • UTF-8 인코딩된 텍스트는 일반 ASCII 문자를 제외하고는 특수화된 단일 바이트 인코딩보다 큽니다. 라틴 문자가 아닌 문자를 위쪽 반(대부분의 키릴 문자 및 그리스 문자 코드 페이지)에 인코딩한 8비트 문자 집합을 사용한 스크립트의 경우 UTF-8의 문자는 크기가 두 배가 됩니다. 태국어데바나가리(다양한 남아시아 언어에서 사용됨)와 같은 일부 스크립트의 경우 문자의 크기가 세 배로 증가합니다. 심지어 유니코드에서 단일 바이트가 복합 문자로 바뀌어 UTF-8에서 6배 더 큰 예도 있습니다. 이것은 인도와 다른 나라들에서 이의를 제기했습니다.[citation needed]
  • UTF-8(또는 다른 멀티바이트 인코딩)에서는 문자열을 문자 중간에 분할하거나 자르는 것이 가능합니다. 문자로 해석하기 전에 두 조각을 나중에 다시 추가하지 않으면 이전 섹션의 끝과 다음 섹션의 시작 모두에서 잘못된 시퀀스가 발생할 수 있으며 일부 디코더는 이러한 바이트를 보존하지 않고 데이터 손실을 초래합니다. 그러나 UTF-8은 자체 동기화하기 때문에 다른 유효한 문자를 사용하지 않을 뿐만 아니라 잘라내기 지점을 문자의 시작 부분으로 다시 이동하는 것도 상당히 쉽습니다.
  • 코드 포인트가 모두 동일한 크기이면 고정된 개수의 측정이 쉽습니다. "문자"가 "바이트"의 동의어로 사용되는 ASCII 시대의 문서 때문에 이것은 종종 중요하게 여겨집니다. 그러나 문자열 위치를 "문자" 대신 바이트를 사용하여 측정함으로써 대부분의 알고리즘은 쉽고 효율적으로 UTF-8에 적응할 수 있습니다. 예를 들어 긴 문자열 내에서 문자열을 검색하는 것은 바이트 단위로 수행될 수 있습니다. 자체 동기화 속성은 거짓 양성을 방지합니다.

기타멀티바이트

  • UTF-8은 모든 유니코드 문자를 인코딩할 수 있습니다. 올바른 코드 페이지나 글꼴을 선택할 필요 없이 다양한 스크립트의 파일을 올바르게 표시할 수 있습니다. 예를 들어, 중국어와 아랍어는 인코딩을 지정하는 특수 마크업이나 수동 설정 없이 동일한 파일로 작성할 수 있습니다.
  • UTF-8은 자체 동기화 중입니다. 어느 방향으로든 잘 정의된 비트 패턴을 스캔하여 문자 경계를 쉽게 식별할 수 있습니다. 오류 또는 손상으로 인해 바이트가 손실된 경우 다음 유효한 문자를 항상 찾고 처리를 재개할 수 있습니다. 지정된 필드에 맞게 문자열을 줄여야 하는 경우 이전에 유효한 문자를 쉽게 찾을 수 있습니다. Shift JIS와 같은 많은 멀티바이트 인코딩은 재동기화하기가 훨씬 어렵습니다. 이것은 또한 바이트 지향 문자열 검색 알고리즘을 UTF-8(문자가 그 많은 바이트로 구성된 "단어"와 동일하기 때문에)과 함께 사용할 수 있다는 것을 의미하며, 하드웨어 지원 및 256개의 엔트리만 있는 룩업 테이블로 인해 최적화된 버전의 바이트 검색이 훨씬 더 빨라질 수 있습니다. 그러나 자체 동기화를 수행하려면 비트가 모든 바이트에서 이러한 마커에 대해 예약되어 크기가 증가해야 합니다.
  • 간단한 비트 단위 연산을 사용하여 효율적으로 인코딩할 수 있습니다. UTF-8은 (Shift JIS, GB 2312 및 기타 인코딩과 달리) 곱셈이나 나눗셈과 같은 느린 수학 연산을 필요로 하지 않습니다.
  • UTF-8은 특정 스크립트를 위해 설계된 멀티바이트 인코딩보다 더 많은 공간을 사용합니다. 동아시아 레거시 인코딩은 일반적으로 문자당 2바이트를 사용했지만 UTF-8에서는 문자당 3바이트를 사용합니다.

UTF-16

  • 바이트 인코딩과 UTF-8은 프로그램에서 바이트 배열로 표현되며, 소스 코드를 바이트 인코딩에서 UTF-8로 변환할 때 함수에 대해 수행할 필요가 없는 경우가 많습니다. UTF-16은 16비트 워드 배열로 표현되며, 기존 ASCII 기반 프로그램과의 호환성을 유지하면서 UTF-16으로 변환하려면 문자열을 복제해야 하는 모든 API 및 데이터 구조가 필요합니다. 하나의 버전은 바이트 문자열을, 다른 버전은 UTF-16을 받아들입니다. 하위 호환성이 필요하지 않은 경우에도 모든 문자열 처리를 수정해야 합니다.
  • UTF-8로 인코딩된 텍스트는 U+0800 범위보다 U+0080 아래의 코드 포인트가 더 많은 경우 UTF-16으로 인코딩된 동일한 텍스트보다 더 작을 것입니다.U+FFFFF. 이것은 모든 현대 유럽 언어에 해당됩니다. 일반적인 파일의 공백, 새 줄, 숫자 및 HTML 마크업으로 인해 중국어와 같은 언어에서도 종종 사실입니다.
  • 대부분의 통신(예: HTML 및 IP)과 스토리지(예: 유닉스용)는 바이트 스트림을 위해 설계되었습니다. UTF-16 문자열은 각 코드 단위에 대해 한 쌍의 바이트를 사용해야 합니다.
    • 이 두 바이트의 순서가 문제가 되며, 예를 들어 BOM(바이트 순서 표시)과 같이 UTF-16 프로토콜에 지정되어야 합니다.
    • UTF-16에서 홀수 바이트가 누락된 경우 문자열 전체가 무의미한 텍스트가 됩니다. UTF-8에서 누락된 바이트는 여전히 누락된 바이트 이후 다음 문자부터 텍스트를 정확하게 복구할 수 있습니다.

파생상품

다음 구현은 UTF-8 사양과 약간의 차이가 있습니다. 이들은 UTF-8 규격과 호환되지 않으며, UTF-8 응용 프로그램을 준수함으로써 거부될 수 있습니다.

CESU-8

Unicode Technical Report #26은[78] CESU-8이라는 이름을 UTF-8의 비표준 변형에 할당하고 있는데, 여기서 보충 평면의 유니코드 문자는 UTF-8에서 필요한 4바이트가 아니라 6바이트를 사용하여 인코딩됩니다. CESU-8 인코딩은 4바이트 UTF-16 대리 쌍의 각 절반을 2바이트 UCS-2 문자로 취급합니다. 두 개의 3바이트 UTF-8 문자를 생성하며, 이들은 모두 원래의 보조 문자를 나타냅니다. 기본 다국어 평면 내의 유니코드 문자는 UTF-8에서 일반적으로 나타나는 것처럼 나타납니다. 보고서는 유니코드 컨소시엄이 사용을 거부했음에도 불구하고 CESU-8로 인코딩된 데이터의 존재를 인정하고 공식화하기 위해 작성되었으며, CESU-8 인코딩의 의도적인 이유는 UTF-16 이진 대조의 보존이라는 점에 주목합니다.

CESU-8 인코딩은 UCS-2 데이터를 가정한 변환 방법을 사용하여 보조 문자가 포함된 UTF-16 데이터를 UTF-8로 변환할 수 있으므로 4바이트 UTF-16 보조 문자를 인식하지 못합니다. 주로 마이크로소프트 윈도우와 같이 내부적으로 UTF-16을 광범위하게 사용하는 운영 체제의 문제입니다.[citation needed]

Oracle Database에서 UTF8 문자 집합은 CESU-8 인코딩을 사용하며 사용하지 않습니다.AL32UTF8 문자 집합은 표준 준수 UTF-8 인코딩을 사용하며 선호됩니다.[79][80]

CESU-8은 HTML5 문서에서 사용이 금지되어 있습니다.[81][82][83]

MySQL utf8mb3

MySQL에서는 utf8mb3 문자 집합은 문자당 최대 3바이트의 UTF-8 인코딩 데이터로 정의되며, 이는 기본 다국어 평면의 유니코드 문자(즉, UCS-2의)만 지원된다는 것을 의미합니다. 보조 평면의 유니코드 문자는 명시적으로 지원되지 않습니다. utf8mb3 더 이상 사용할 수 없습니다. utf8mb4 문자 집합, 표준 준수 UTF-8 인코딩을 사용합니다. utf8 에 대한 별칭입니다. utf8mb3, 그러나 에일리어스가 될 의도입니다. utf8mb4 MySQL의 향후 릴리스에서.[14] 지원되지 않지만 CESU-8 인코딩된 데이터를 다음과 같이 저장할 수 있습니다. utf8mb3, UTF-16 데이터를 UCS-2인 것처럼 보조 문자로 처리합니다.

수정 UTF-8

수정된 UTF-8(MUTF-8)은 자바 프로그래밍 언어에서 비롯되었습니다. 수정된 UTF-8에서 널 문자(U+0000)는 000000000000(16진수 00) 대신 2바이트 오버롱 인코딩 11000000100000(16진수 C080)을 사용합니다.[84] 수정된 UTF-8 문자열은 실제 Null 바이트를 포함하지 않지만 U+0000을 포함한 모든 유니코드 코드 포인트를 포함할 수 있으며,[85] 이를 통해 (Null 바이트가 추가된) 이러한 문자열을 기존의 Null-termined 문자열 함수에서 처리할 수 있습니다. 알려진 모든 수정된 UTF-8 구현은 또한 대리 쌍을 CESU-8에서와 같이 취급합니다.

일반적으로 이 언어는 문자열을 읽고 쓸 때 표준 UTF-8을 지원합니다. InputStreamReader 그리고. OutputStreamWriter (플랫폼의 기본 문자 집합이거나 프로그램에서 요청한 경우). 그러나 다른 응용 프로그램 중에서 객체 직렬화[86] 위해 Modified UTF-8을 사용합니다. DataInput 그리고. DataOutput, 자바 네이티브 인터페이스[87]클래스 파일에 일정한 문자열을 포함하기 위한 것입니다.[88]

Dalvik이 정의한 덱스 형식도 문자열 값을 나타내기 위해 동일한 수정된 UTF-8을 사용합니다.[89] 또한 Tcl은 Unicode 데이터의 내부 표현을 위해 Java와 동일한 수정된 UTF-8을[90] 사용하지만 외부 데이터를 위해 엄격한 CESU-8을 사용합니다.

WTF-8

WTF-8(Wobbly Transformation Format, 8비트)에서는 짝을 이루지 않은 대리 반쪽(U+D800 ~ U+DFFF)이 허용됩니다.[91] 이 작업은 윈도우즈 파일 이름과 같이 유효하지 않은 UTF-16을 저장하는 데 필요합니다. UTF-8을 다루는 많은 시스템은 더 간단하기 때문에 다른 인코딩을 고려하지 않고 이러한 방식으로 작동합니다.[92]

"WTF-8"이라는 용어는 때때로 CP1252 바이트만이 유일하게 인코딩된다는 암시와 함께 잘못 이중 인코딩된 UTF-8[93][94] 지칭하는 데 유머러스하게 사용되었습니다.[95]

PEP 383

파이썬 프로그래밍 언어 버전 3은 유효하지 않은 UTF-8 바이테스트스트림의 각 바이트를 오류로 취급합니다(파이썬 3.7의[96] 새로운 UTF-8 모드 변경도 참조). 이것은 128개의 가능한 오류를 제공합니다. 128개의 가능한 오류 바이트를 예약된 코드 포인트로 변환하고 해당 코드 포인트를 다시 오류 바이트로 변환하여 UTF-8을 출력함으로써 UTF-8로 가정되는 모든 바이트 시퀀스를 무손실로 변환할 수 있도록 확장이 생성되었습니다. 가장 일반적인 접근 방식은 코드를 U+DC80으로 변환하는 것입니다...PythonPEP 383(또는 "대리 탈출") 접근 방식에서 사용되는 낮은 (추적) 대리 값이며 따라서 "무효"인 UTF-16입니다.[32] MirBSD OPTU-8/16이라는 또 다른 인코딩은 이들을 U+EF80으로 변환합니다...개인 용도 지역의 U+EFF.[97] 두 접근 방식 중 하나에서 바이트 값은 출력 코드 포인트의 하위 8비트로 인코딩됩니다.

이러한 인코딩은 "잘못된" 바이트 문자열을 나중에 처리할 필요가 없고 "텍스트"와 "데이터" 바이트 배열이 동일한 개체가 될 수 있기 때문에 매우 유용합니다. 프로그램이 UTF-16을 내부적으로 사용하려면 잘못된 UTF-8을 사용할 수 있는 파일 이름을 보존하고 사용해야 합니다.[98] Windows 파일 시스템 API가 UTF-16을 사용하므로 잘못된 UTF-8을 지원할 필요성이 적습니다.[32]

인코딩이 가역적이 되려면 잘못된 바이트에 사용되는 코드 포인트의 표준 UTF-8 인코딩이 유효하지 않은 것으로 간주되어야 합니다. 따라서 인코딩이 WTF-8 또는 CESU-8과 호환되지 않습니다(128개 코드 포인트의 경우에만 해당). 다시 인코딩할 때는 유효한 UTF-8로 다시 변환되는 오류 코드 포인트 시퀀스를 주의해야 합니다. 이는 악의적인 소프트웨어가 출력에서 예기치 않은 문자를 얻기 위해 사용할 수 있지만 ASCII 문자를 생성할 수 없기 때문에 비교적 안전한 것으로 간주됩니다. 악의적인 시퀀스(사이트스크립팅 등)는 일반적으로 ASCII 문자에 의존하기 때문입니다.[98]

참고 항목

메모들

  1. ^ 17개의 비행기에 2개의 코드 포인트를 곱해서 기술적으로 2개의 invalid 대리기를 뺀 값입니다.
  2. ^ 최대 0x1 FFFF까지 인코딩할 수 있는 충분한 데이터 비트가 있지만, 현재 RFC 3629 §3은 UTF-8 인코딩을 U+10FFF로 제한하여 UTF-16의 20비트 제한을 초과하는 인코딩의 순환을 방지합니다. 오래된 RFC 2279는 UTF-8 인코딩을 U+7 코드 포인트까지 허용했습니다.FFF FFF, 최대 27비트의 인코딩된 값을 허용합니다. 이러한 이유로, UTF-8 멀티바이트 코드 시퀀스의 첫 번째 바이트가 F0에서 F4까지의 값으로 제한되더라도, 새로운 제한에 부합하는 인코딩으로 올바르게 작동하기 위해 오래된 디코딩 소프트웨어를 업데이트할 필요가 엄격하게 필요하지 않았기 때문에, 이러한 제한을 시행하지 못한 일부 오래된 소프트웨어는 여전히 사용 중입니다.
  3. ^ 일부 복잡한 이모티콘 문자는 이보다 훨씬 더 많은 것을 취할 수 있습니다. 트랜스젠더 플래그 이모티콘(🏳️⚧️)은 5개의 코드 포인트 시퀀스 U+1F3F3 U+FE0F U+200D U+26A7 U+FE0F로 구성되어 있으며, 스코틀랜드의 플래그(🏴󠁧󠁢󠁳󠁣󠁴󠁿)의 경우 7개의 코드 포인트 시퀀스 U+1F3F4 U+E0067 U+E0062 U+E0073 U+E0063 U+E0074 U+E007F에 대해 총 28바이트가 필요합니다.
  4. ^ 예를 들어, 셀 9D는 +1D라고 말합니다. 이진법의 16진수 9D는 10011101이고, 가장 높은 2비트(10)는 이것을 연속 바이트로 표시하기 위해 예약되므로, 나머지 6비트(011101)는 1D의 16진수 값을 갖습니다.
  5. ^ "이 PEP는 Windows의 기본 파일 시스템 인코딩을 로 변경하고, 파일 시스템 경로에 유니코드 API를 사용하도록 모든 파일 시스템 기능을 변경할 것을 제안합니다. [...]은(는) 경로에 사용되는 모든 문자를 올바르게 왕복할 수 있습니다. surrogateescape 처리; Windows에서 다음과 같은 이유로 str 네이티브 표현에 대한 지도). Windows에서 바이트는 경로에 사용되는 모든 문자를 왕복할 수 없습니다."[28]
  6. ^
    1바이트 128 = 128
    2바이트 ( 16 + 5 ) × 64 = 1344
    3바이트 5 × 64 × 64 = + 20480
    21952

    각 연속 바이트에 대해 더 정확한 테스트를 수행하면 다소 적을 수 있습니다.

  7. ^ W3Techs.com 조사는 서버의 응답에 명시된 인코딩을 기반으로 합니다. https://w3techs.com/forum/topic/22994 를 참조하십시오.
  8. ^ 다른 라이브러리와의 상호작용은 종종 일종의 내부 표현을 필요로 하기 때문에, 규격은 문자열을 C 코드에 노출시키는 권장 방법으로 UTF-8을 선택합니다. [...] 문자열이 ASCII 문자만 사용하는 경우 데이터와 UTF8 포인터는 동일한 메모리를 가리킵니다(라틴-1만 사용하는 것은 충분하지 않습니다). [...] 유니코드 개체를 만드는 권장 방법은 함수 PyUnicode_New [...]를 사용하는 것입니다. 새로운 함수 PyUnicode_AsUTF-8 표현에 액세스하기 위해 UTF8이 제공됩니다.[59]
  9. ^ UTF-8로 전환하면 문자열의 장기적인 목표 중 하나를 달성하여 고성능 처리를 가능하게 하며, [...] 또한 향후 더욱 성능이 뛰어난 API를 제공할 수 있는 기반을 마련합니다.[61]
  10. ^ 기존 유니코드 개체를 삭제하기 전까지는 PyPy의 UTF-8 기반 구현과 같은 다른 유니코드 구현을 시도하는 것이 매우 어렵습니다.[64]
  11. ^ 예를 들어, UTF-8 지원 대조를 사용하여 기존 열 데이터 유형을 NCHAR(10)에서 CHAR(10)로 변경하면 스토리지 요구 사항이 거의 50% 감소합니다. [...] ASCII 범위에서 UTF-8에서 집중적인 읽기/쓰기 I/O를 수행할 때, 문자열 열에 비클러스터 인덱스가 있는 클러스터링된 테이블을 사용하여 UTF-16에 비해 평균 35%의 성능 향상을, 힙을 사용하여 UTF-16에 비해 평균 11%의 성능 향상을 측정했습니다.[67]
  12. ^ Windows 버전 1903(2019년 5월 업데이트)의 경우 패키지 앱의 경우 appxmanifest에서 ActiveCodePage 속성을 사용하거나 패키지가 해제된 앱의 경우 퓨전 매니페스트를 사용하여 프로세스가 UTF-8을 프로세스 코드 페이지로 사용하도록 강제할 수 있습니다. [...] CP_ACP 에 해당하는 CP_UTF8 Windows 버전 1903(2019년 5월 업데이트) 이상에서 실행되고 위에서 설명한 ActiveCodePage 속성이 UTF-8로 설정된 경우에만 해당하며, 그렇지 않으면 레거시 시스템 코드 페이지를 보호합니다. 사용하는 것이 좋습니다. CP_UTF8 노골적으로
  13. ^ "UTF-8에서 작동하면 호환성을 최대한 보장할 수 있습니다. [...] Windows는 MultiByteToWideChar 및 WideCharToMultiByte를 사용하여 코드 페이지 변환이 필요한 UTF-16(또는 WCHAR)에서 기본적으로 작동합니다. 이것은 Windows가 여러 플랫폼을 대상으로 하는 코드에 부여하는 고유한 부담입니다. [...] 일반적으로 Microsoft Game Development Kit(GDK)와 Windows는 UTF-8을 지원하여 여러 플랫폼 및 웹을 대상으로 하거나 상호 교환하는 코드에 대한 Windows의 고유한 부담을 제거하려고 합니다. 또한 앱과 게임의 국제화 문제가 줄어들고 이를 제대로 파악하는 데 필요한 테스트 매트릭스가 줄어듭니다."[7]

참고문헌

  1. ^ "Chapter 2. General Structure". The Unicode Standard (6.0 ed.). Mountain View, California, US: The Unicode Consortium. ISBN 978-1-936213-01-6.
  2. ^ a b Pike, Rob (30 April 2003). "UTF-8 history".
  3. ^ Pike, Rob; Thompson, Ken (1993). "Hello World or Καλημέρα κόσμε or こんにちは 世界" (PDF). Proceedings of the Winter 1993 USENIX Conference.
  4. ^ "File System Safe UCS - Transformation Format (FSS-UTF) - X/Open Preliminary Specification" (PDF). unicode.org.
  5. ^ "USENIX Winter 1993 Conference Proceedings". usenix.org.
  6. ^ a b Alvestrand, Harald T. (January 1998). IETF Policy on Character Sets and Languages. IETF. doi:10.17487/RFC2277. BCP 18. RFC 2277.
  7. ^ a b c "UTF-8 support in the Microsoft GDK". learn.microsoft.com. Microsoft Game Development Kit (GDK). Retrieved 2023-03-05.
  8. ^ a b "Encoding Standard". encoding.spec.whatwg.org. Retrieved 2020-04-15.
  9. ^ a b c "Usage Survey of Character Encodings broken down by Ranking". W3Techs. Retrieved 2024-02-13.
  10. ^ "Encoding Standard § 4.2. Names and labels". WHATWG. Retrieved 2018-04-29.
  11. ^ "Character Sets". Internet Assigned Numbers Authority. 2013-01-23. Retrieved 2013-02-08.
  12. ^ Liviu (2014-02-07). "UTF-8 codepage 65001 in Windows 7 - part I". Retrieved 2018-01-30. Previously under XP (and, unverified, but probably Vista, too) for loops simply did not work while codepage 65001 was active
  13. ^ "MySQL :: MySQL 8.0 Reference Manual :: 10.9.1 The utf8mb4 Character Set (4-Byte UTF-8 Unicode Encoding)". MySQL 8.0 Reference Manual. Oracle Corporation. Retrieved 2023-03-14.
  14. ^ a b "MySQL :: MySQL 8.0 Reference Manual :: 10.9.2 The utf8mb3 Character Set (3-Byte UTF-8 Unicode Encoding)". MySQL 8.0 Reference Manual. Oracle Corporation. Retrieved 2023-02-24.
  15. ^ "HP PCL Symbol Sets Printer Control Language (PCL & PXL) Support Blog". 2015-02-19. Archived from the original on 2015-02-19. Retrieved 2018-01-30.
  16. ^ "Database Globalization Support Guide". docs.oracle.com. Retrieved 2023-03-16.
  17. ^ "BOM". suikawiki (in Japanese). Archived from the original on 2009-01-17.
  18. ^ Davis, Mark. "Forms of Unicode". IBM. Archived from the original on 2005-05-06. Retrieved 2013-09-18.
  19. ^ "String". Apple Developer. Retrieved 2021-03-15.
  20. ^ "Chapter 3" (PDF), The Unicode Standard, p. 54
  21. ^ "Chapter 3" (PDF), The Unicode Standard, p. 55
  22. ^ "Chapter 3" (PDF), The Unicode Standard, p. 55
  23. ^ a b c Yergeau, F. (November 2003). UTF-8, a transformation format of ISO 10646. IETF. doi:10.17487/RFC3629. STD 63. RFC 3629. Retrieved August 20, 2020.
  24. ^ "Chapter 3" (PDF), The Unicode Standard, p. 54
  25. ^ "Chapter 3" (PDF), The Unicode Standard, p. 55
  26. ^ Marin, Marvin (2000-10-17). Windows NT UNICODE vulnerability analysis. Web server folder traversal. SANS Institute (Report). Malware FAQ. MS00-078. Archived from the original on Aug 27, 2014.
  27. ^ "CVE-2008-2938". National Vulnerability Database (nvd.nist.gov). U.S. National Institute of Standards and Technology. 2008.
  28. ^ "Change Windows filesystem encoding to UTF-8". Python.org. PEP 529. Retrieved 2022-05-10.
  29. ^ "DataInput". docs.oracle.com. Java Platform SE 8). Retrieved 2021-03-24.
  30. ^ "Non-decodable bytes in system character interfaces". python.org. 2009-04-22. Retrieved 2014-08-13.
  31. ^ Unicode 6.0.0. unicode.org (Report). October 2010.
  32. ^ a b c von Löwis, Martin (2009-04-22). "Non-decodable Bytes in System Character Interfaces". Python Software Foundation. PEP 383.
  33. ^ "Chapter 2" (PDF), The Unicode Standard - Version 15.0.0, p. 39
  34. ^ "UTF-8 and Unicode FAQ for Unix/Linux".
  35. ^ Davis, Mark (2012-02-03). "Unicode over 60 percent of the web". Official Google blog. Archived from the original on 2018-08-09. Retrieved 2020-07-24.
  36. ^ Davis, Mark (2008-05-05). "Moving to Unicode 5.1". Official Google blog. Retrieved 2023-03-13.
  37. ^ "Usage statistics and market share of ASCII for websites". W3Techs. January 2024. Retrieved 2024-01-01.
  38. ^ Bray, Tim (December 2017). Bray, Tim (ed.). The JavaScript Object Notation (JSON) Data Interchange Format. IETF. doi:10.17487/RFC8259. RFC 8259. Retrieved 16 February 2018.
  39. ^ "Using International Characters in Internet Mail". Internet Mail Consortium. 1998-08-01. Archived from the original on 2007-10-26. Retrieved 2007-11-08.
  40. ^ "Encoding Standard". encoding.spec.whatwg.org. Retrieved 2018-11-15.
  41. ^ "Specifying the document's character encoding". HTML 5.2 (Report). World Wide Web Consortium. 14 December 2017. Retrieved 2018-06-03.
  42. ^ "Choose text encoding when you open and save files". Microsoft Support (support.microsoft.com). Retrieved 2021-11-01.
  43. ^ "UTF-8 - Character encoding of Microsoft Word DOC and DOCX files?". Stack Overflow. Retrieved 2021-11-01.
  44. ^ "Exporting a UTF-8 .txt file from Word". support.3playmedia.com.
  45. ^ "Are XLSX files UTF-8 encoded, by definition?". Stack Overflow. Excel. Retrieved 2021-11-01.
  46. ^ Abhinav, Ankit; Xu, Jazlyn (April 13, 2020). "How to open UTF-8 CSV file in Excel without mis-conversion of characters in Japanese and Chinese language for both Mac and Windows?". Microsoft Support Community. Retrieved 2021-11-01.
  47. ^ "How can I make Notepad to save text in UTF-8 without the BOM?". Stack Overflow. Retrieved 2021-03-24.
  48. ^ Galloway, Matt (October 2012). "Character encoding for iOS developers; or, UTF-8 what now?". www.galloway.me.uk. Retrieved 2021-01-02. ... in reality, you usually just assume UTF-8 since that is by far the most common encoding.
  49. ^ "Windows 10 Notepad is getting better UTF-8 encoding support". BleepingComputer. Retrieved 2021-03-24. Microsoft is now defaulting to saving new text files as UTF-8 without BOM, as shown below.
  50. ^ "Customize the Windows 11 Start menu". docs.microsoft.com. Retrieved 2021-06-29. Make sure your LayoutModification.json uses UTF-8 encoding.
  51. ^ "UTF-8 by default". openjdk.java.net. JEP 400. Retrieved 2022-03-30.
  52. ^ "Set default for Encoding.default_external to UTF-8 on Windows". Ruby Issue Tracking System (bugs.ruby-lang.org). Ruby master. Feature #16604. Retrieved 2022-08-01.
  53. ^ "Feature #12650: Use UTF-8 encoding for ENV on Windows". Ruby Issue Tracking System (bugs.ruby-lang.org). Ruby master. Retrieved 2022-08-01.
  54. ^ "New features in R 4.2.0". R bloggers (r-bloggers.com). The Jumping Rivers Blog. 2022-04-01. Retrieved 2022-08-01.
  55. ^ "add a new UTF-8 mode". peps.python.org. PEP 540. Retrieved 2022-09-23.
  56. ^ "Make UTF-8 mode default". peps.python.org. PEP 686. Retrieved 2023-07-26.
  57. ^ "Add optional EncodingWarning". Python.org. PEP 597. Retrieved 2021-08-24.
  58. ^ Support for UTF-8 as a portable source file encoding (PDF). open-std.org (Report). 2022. p2295r6.
  59. ^ a b "Flexible String Representation". Python.org. PEP 393. Retrieved 2022-05-18.
  60. ^ "Source code representation". The Go Programming Language Specification. golang.org (Report). Retrieved 2021-02-10.
  61. ^ Tsai, Michael J. (21 March 2019). "UTF-8 string in Swift 5" (blog post). Retrieved 2021-03-15.
  62. ^ "PyPy v7.1 released; now uses UTF-8 internally for Unicode strings". Mattip. PyPy status blog. 2019-03-24. Retrieved 2020-11-21.
  63. ^ "Unicode objects and codecs". Python documentation. Retrieved 2023-08-19. UTF-8 representation is created on demand and cached in the Unicode object.
  64. ^ "PEP 623 – remove wstr from Unicode". Python.org. Retrieved 2020-11-21.
  65. ^ Wouters, Thomas (2023-07-11). "Python 3.12.0 beta 4 released". Python Insider (pythoninsider.blogspot.com) (blog post). Retrieved 2023-07-26. The deprecated wstr and wstr_length members of the C implementation of unicode objects were removed, per PEP 623.
  66. ^ "validate-charset (validate for compatible characters)". docs.microsoft.com. Retrieved 2021-07-19. Visual Studio uses UTF-8 as the internal character encoding during conversion between the source character set and the execution character set.
  67. ^ "Introducing UTF-8 support for SQL Server". techcommunity.microsoft.com. 2019-07-02. Retrieved 2021-08-24.
  68. ^ "Use the Windows UTF-8 code page – UWP applications". docs.microsoft.com. Retrieved 2020-06-06.
  69. ^ "Appendix F. FSS-UTF / File System Safe UCS Transformation format" (PDF). The Unicode Standard 1.1. Archived (PDF) from the original on 2016-06-07. Retrieved 2016-06-07.
  70. ^ Whistler, Kenneth (2001-06-12). "FSS-UTF, UTF-2, UTF-8, and UTF-16". Archived from the original on 2016-06-07. Retrieved 2006-06-07.
  71. ^ a b Pike, Rob (2003-04-30). "UTF-8 history". Retrieved 2012-09-07.
  72. ^ Pike, Rob (2012-09-06). "UTF-8 turned 20 years old yesterday". Retrieved 2012-09-07.
  73. ^ ISO/IEC 10646:2014 §9.1, 2014.
  74. ^ 유니코드 표준, 버전 15.0 § 3.9 D92, § 3.10 D95, 2021.
  75. ^ Unicode Standard Annex #27: Unicode 3.1, 2001.
  76. ^ 유니코드 표준, 버전 5.0 § 3.9 – § 3.10 ch. 2006.
  77. ^ Unicode Standard, Version 6.0 § 3.9 D92, § 3.10 D95, 2010.
  78. ^ McGowan, Rick (2011-12-19). "Compatibility Encoding Scheme for UTF-16: 8-Bit (CESU-8)". Unicode Consortium. Unicode Technical Report #26.
  79. ^ "Character Set Support". Oracle Database 19c Documentation, SQL Language Reference. Oracle Corporation.
  80. ^ "Supporting Multilingual Databases with Unicode § Support for the Unicode Standard in Oracle Database". Database Globalization Support Guide. Oracle Corporation.
  81. ^ "8.2.2.3. Character encodings". HTML 5.1 Standard. W3C.
  82. ^ "8.2.2.3. Character encodings". HTML 5 Standard. W3C.
  83. ^ "12.2.3.3 Character encodings". HTML Living Standard. WHATWG.
  84. ^ "Java SE documentation for Interface java.io.DataInput, subsection on Modified UTF-8". Oracle Corporation. 2015. Retrieved 2015-10-16.
  85. ^ "The Java Virtual Machine Specification, section 4.4.7: "The CONSTANT_Utf8_info Structure"". Oracle Corporation. 2015. Retrieved 2015-10-16.
  86. ^ "Java Object Serialization Specification, chapter 6: Object Serialization Stream Protocol, section 2: Stream Elements". Oracle Corporation. 2010. Retrieved 2015-10-16.
  87. ^ "Java Native Interface Specification, chapter 3: JNI Types and Data Structures, section: Modified UTF-8 Strings". Oracle Corporation. 2015. Retrieved 2015-10-16.
  88. ^ "The Java Virtual Machine Specification, section 4.4.7: "The CONSTANT_Utf8_info Structure"". Oracle Corporation. 2015. Retrieved 2015-10-16.
  89. ^ "ART and Dalvik". Android Open Source Project. Archived from the original on 2013-04-26. Retrieved 2013-04-09.
  90. ^ "UTF-8 bit by bit". Tcler's Wiki. 2001-02-28. Retrieved 2022-09-03.
  91. ^ Sapin, Simon (2016-03-11) [2014-09-25]. "The WTF-8 encoding". Archived from the original on 2016-05-24. Retrieved 2016-05-24.
  92. ^ Sapin, Simon (2015-03-25) [2014-09-25]. "The WTF-8 encoding § Motivation". Archived from the original on 2020-08-16. Retrieved 2020-08-26.
  93. ^ "WTF-8.com". 2006-05-18. Retrieved 2016-06-21.
  94. ^ Speer, Robyn (2015-05-21). "ftfy (fixes text for you) 4.0: changing less and fixing more". Archived from the original on 2015-05-30. Retrieved 2016-06-21.
  95. ^ "WTF-8, a transformation format of code page 1252". Archived from the original on 2016-10-13. Retrieved 2016-10-12.
  96. ^ "PEP 540 -- Add a new UTF-8 Mode". Python.org. Retrieved 2021-03-24.
  97. ^ "RTFM optu8to16(3), optu8to16vis(3)". www.mirbsd.org.
  98. ^ a b Davis, Mark; Suignard, Michel (2014). "3.7 Enabling Lossless Conversion". Unicode Security Considerations. Unicode Technical Report #36.

외부 링크