UTF-8: Unicode TransformationFormat-8bit, BOM은 허용되지만 일반적으로 BOM은 포함되지 않습니다. 국제 문자를 해결하는 데 사용되는 멀티바이트 인코딩입니다. 영어의 경우 8비트(즉, 1바이트)를 사용하고 중국어의 경우 24비트(3바이트)를 사용합니다. UTF-8은 전 세계 모든 국가에서 사용되는 문자를 포함하며 국제적인 인코딩이며 다양한 용도로 사용됩니다. UTF-8로 인코딩된 텍스트는 UTF8 문자 집합을 지원하는 다양한 국가의 브라우저에 표시될 수 있습니다. 예를 들어 UTF8 인코딩인 경우 외국인의 영어 IE에서도 중국어가 표시될 수 있으므로 IE의 중국어 지원 패키지를 다운로드할 필요가 없습니다.
GBK는 국가 표준 GB2312를 기반으로 한 표준이며 GB2312와 호환되도록 확장되었습니다. GBK의 텍스트 인코딩은 더블바이트로 표현됩니다. 즉, 한자와 영어 문자 모두 더블바이트로 표현됩니다. 한자를 구별하기 위해 최상위 비트가 1로 설정됩니다. GBK는 모든 중국어 문자를 포함하며 UTF8보다 다목적성이 떨어지지만 UTF8은 GBD보다 더 큰 데이터베이스를 차지합니다.
GBK, GB2312 등은 유니코드 인코딩을 통해 UTF8로 변환되어야 합니다.
GBK, GB2312--유니코드--UTF8
UTF8--유니코드--GBK, GB2312
웹사이트나 포럼의 경우 영문자가 많으면 공간 절약을 위해 UTF-8을 사용하는 것이 좋습니다. 그러나 현재 많은 포럼 플러그인은 일반적으로 GBK만 지원합니다.
인코딩 차이에 대한 자세한 설명 간단히 말하면 유니코드, gbk, 빅파이브 코드가 인코딩된 값이고, utf-8, uft-16 등이 이 값의 표현입니다. 앞의 3개 코드는 같은 한자라도 호환이 되는데, 3개 코드 값이 전혀 다릅니다. 예를 들어 "Han"의 uncode 값이 gbk와 다르다고 가정하면, uncode가 a040이고 gbk가 b030이고, uft-8 코드가 그 값을 표현한 형태라고 가정해보자. utf-8 코드는 완전히 uncode용으로만 구성되어 있습니다. GBK가 UTF-8로 변환하려면 먼저 uncode로 변환한 후 utf-8로 변환하면 괜찮습니다.
자세한 내용은 아래 재인쇄된 기사를 참조하세요.
유니코드 인코딩에 대해 이야기하고 UCS, UTF, BMP, BOM과 같은 용어를 간략하게 설명하겠습니다. 이 내용은 프로그래머를 위해 작성된 흥미로운 내용입니다. 소위 재미란 이전에 명확하지 않았던 일부 개념을 쉽게 이해하고 지식을 향상시킬 수 있다는 것을 의미하며 이는 RPG 게임의 업그레이드와 유사합니다. 이 글을 구성하게 된 동기는 두 가지 질문입니다.
질문 1:
Windows 메모장에서 "다른 이름으로 저장"을 사용하면 GBK, 유니코드, 유니코드 빅 엔디안 및 UTF-8 인코딩 방법 간에 변환할 수 있습니다. 또는 온라인 변환을 위해 http://www.knowsky.com/tools/utf8.asp 로 직접 이동할 수 있습니다.
txt 파일이기도 합니다. Windows는 인코딩 방법을 어떻게 식별합니까?
나는 오래 전에 유니코드, 유니코드 빅엔디안 및 UTF-8로 인코딩된 txt 파일의 시작 부분에 FF, FE(유니코드), FE, FF(유니코드 빅엔디안), EF, BB, BF와 같은 몇 바이트가 더 있다는 것을 발견했습니다. (UTF-8). 그러면 이러한 마커는 어떤 기준을 기반으로 하는 것일까요?
질문 2:
최근 인터넷에서 UTF-32, UTF-16, UTF-8의 상호 변환을 구현하는 ConvertUTF.c를 보았습니다. 저는 이미 유니코드(UCS2), GBK, UTF-8과 같은 인코딩 방법에 대해 알고 있습니다. 하지만 이 프로그램은 나를 약간 혼란스럽게 만들고 UTF-16과 UCS2의 관계가 무엇인지 기억이 나지 않습니다.
관련 정보를 확인한 후 마침내 이러한 문제를 명확히 하고 유니코드에 대한 세부 정보도 배웠습니다. 기사를 작성하여 비슷한 질문이 있는 친구에게 보내보세요. 이 기사는 가능한 한 이해하기 쉽게 작성되었지만 독자는 바이트가 무엇인지, 16진수가 무엇인지 알아야 합니다.
0. 빅엔디안과 리틀엔디안
빅 엔디안과 리틀 엔디안은 CPU가 멀티바이트 숫자를 처리하는 다른 방식입니다. 예를 들어 "汉" 문자의 유니코드 인코딩은 6C49입니다. 그러면 파일에 쓸 때 6C를 앞에 써야 할까요, 아니면 49를 앞에 써야 할까요? 앞에 6C라고 쓰면 빅엔디안이다. 앞에 49가 적혀 있으면 리틀 엔디안입니다.
"엔디안"이라는 단어는 "걸리버 여행기"에서 유래되었습니다. 릴리푸트 내전은 빅엔디안과 리틀엔디안 중 어느 쪽의 알을 깨뜨릴 것인가에 따라 일어났고, 그 결과 여섯 명의 황제가 목숨을 잃었고, 또 다른 황제는 왕좌를 잃었다.
우리는 일반적으로 엔디안을 "바이트 순서"로 번역하며, 빅엔디안과 리틀엔디안을 "빅엔드", "리틀엔드"라고 부릅니다.
1. 문자 인코딩 및 내부 코드 그런데, 한자 인코딩 문자는 컴퓨터에서 처리되기 전에 인코딩되어야 합니다. 컴퓨터에서 사용되는 기본 인코딩 방법은 컴퓨터의 내부 코드입니다. 초기 컴퓨터는 중국어 문자를 처리하기 위해 7비트 ASCII 인코딩을 사용했습니다. 프로그래머는 중국어 간체용으로 GB2312를, 중국어 번체용으로 big5를 설계했습니다.
IETF의 RFC2781 및 RFC3629는 UTF-16 및 UTF-8의 인코딩 방법을 RFC의 일관된 스타일로 명확하고 명확하며 엄격하게 설명합니다. IETF가 Internet Engineering Task Force의 약자라는 사실을 늘 잊어버리곤 합니다. 그러나 IETF가 관리하는 RFC는 인터넷상의 모든 사양의 기초입니다.
2.1. 내부 코드 및 코드 페이지
현재 Windows 커널은 이미 유니코드 문자 집합을 지원하므로 커널은 전 세계 모든 언어를 지원할 수 있습니다. 그러나 다수의 기존 프로그램과 문서는 GBK와 같은 특정 언어 인코딩을 사용하기 때문에 Windows가 기존 인코딩을 지원하지 않고 모두 유니코드를 사용하는 것은 불가능합니다.
Windows는 코드 페이지를 사용하여 다양한 국가 및 지역에 적응합니다. 코드 페이지는 앞서 언급한 내부 코드로 이해될 수 있다. GBK에 해당하는 코드 페이지는 CP936입니다.
Microsoft는 GB18030: CP54936에 대한 코드 페이지도 정의합니다. 그러나 GB18030에는 일부 4바이트 인코딩이 있고 Windows 코드 페이지는 1바이트 및 2바이트 인코딩만 지원하므로 이 코드 페이지는 실제로 사용할 수 없습니다.
3. UCS-2, UCS-4, BMP
UCS는 UCS-2와 UCS-4의 두 가지 형식으로 제공됩니다. 이름에서 알 수 있듯이 UCS-2는 2바이트로 인코딩되고 UCS-4는 4바이트로 인코딩됩니다(실제로는 31비트만 사용되며 가장 높은 비트는 0이어야 함). 몇 가지 간단한 수학 게임을 해보자:
UCS-2에는 2^16=65536개의 코드 포인트가 있고 UCS-4에는 2^31=2147483648개의 코드 포인트가 있습니다.
UCS-4는 가장 높은 비트가 0인 최상위 바이트에 따라 2^7=128 그룹으로 나뉩니다. 각 그룹은 다음으로 높은 바이트를 기준으로 256개의 평면으로 나뉩니다. 각 평면은 세 번째 바이트에 따라 256개의 행으로 나뉘며, 각 행에는 256개의 셀이 포함됩니다. 물론, 같은 행의 셀은 마지막 바이트만 다를 뿐 나머지는 동일합니다.
그룹 0의 평면 0을 기본 다국어 평면 또는 BMP라고 합니다. 또는 UCS-4에서는 상위 2바이트가 0인 코드 비트를 BMP라고 합니다.
UCS-2는 UCS-4의 BMP에서 처음 2개의 0바이트를 제거하여 얻습니다. UCS-4의 BMP를 얻으려면 UCS-2의 2바이트 앞에 0바이트 2개를 추가합니다. 현재 UCS-4 사양에는 BMP 외부에 할당된 문자가 없습니다.
4. UTF 인코딩
UTF-8은 UCS를 8비트 단위로 인코딩합니다. UCS-2에서 UTF-8로의 인코딩은 다음과 같습니다.
UCS-2 인코딩(16진수) UTF-8 바이트 스트림(2진수)
0000-007F 0xxxxxxx
0080-07FF 110xxxxx 10xxxxxx
0800 - FFFF 1110xxxx 10xxxxxx 10xxxxxx
예를 들어, "중국어"의 유니코드 인코딩은 6C49입니다. 6C49는 0800-FFFF 사이이므로 3바이트 템플릿(1110xxxx 10xxxxxx10xxxxxx)을 사용해야 합니다. 6C49를 바이너리로 쓰면 0110 110001 001001입니다. 이 비트 스트림을 사용하여 템플릿의 x를 교체하면 1110011010110001 10001001, 즉 E6 B1 89가 됩니다.
독자는 메모장을 사용하여 코딩이 올바른지 테스트할 수 있습니다. UltraEdit는 UTF-8로 인코딩된 텍스트 파일을 열 때 자동으로 UTF-16으로 변환되므로 혼동을 일으킬 수 있다는 점에 유의하세요. 설정에서 이 옵션을 끌 수 있습니다. 더 나은 도구는 Hex Workshop입니다.
UTF-16은 UCS를 16비트 단위로 인코딩합니다. 0x10000보다 작은 UCS 코드의 경우 UTF-16 인코딩은 UCS 코드에 해당하는 16비트 부호 없는 정수와 같습니다. 0x10000 이상의 UCS 코드에 대해서는 알고리즘이 정의됩니다. 그러나 실제로 사용되는 UCS2나 UCS4의 BMP는 0x10000보다 작아야 하므로 현재로서는 UTF-16과 UCS-2는 기본적으로 동일하다고 볼 수 있다. 그러나 UCS-2는 인코딩 방식일 뿐이고 실제 전송에는 UTF-16이 사용되므로 바이트 순서 문제를 고려해야 한다.
5. UTF 바이트 순서 및 BOM
UTF-8은 바이트를 인코딩 단위로 사용하며 엔디안 문제가 없습니다. UTF-16은 2바이트를 인코딩 단위로 사용합니다. UTF-16 텍스트를 해석하기 전에 먼저 각 인코딩 단위의 바이트 순서를 이해해야 합니다. 예를 들어 "Kui"의 유니코드 인코딩은 594E이고 "B"의 유니코드 인코딩은 4E59입니다. UTF-16 바이트 스트림 "594E"를 수신하면 "Ku"입니까, "B"입니까?
유니코드 사양에서 바이트 순서를 표시하는 데 권장되는 방법은 BOM입니다. BOM은 "Bill Of Material"의 BOM 목록이 아니라 Byte order Mark입니다. BOM은 약간 영리한 아이디어입니다.
UCS 인코딩에는 "ZERO WIDTH NO-BREAKSPACE"라는 문자가 있고, 인코딩은 FEFF입니다. FFFE는 UCS에 존재하지 않는 문자이므로 실제 전송에서는 나타나지 않아야 한다. UCS 사양에서는 바이트 스트림을 전송하기 전에 "ZERO WIDTH NO-break SPACE" 문자를 전송할 것을 권장합니다.
이런 식으로 수신기가 FEFF를 수신하면 바이트 스트림이 Big-Endian임을 나타내고, FFFE를 수신하면 바이트 스트림이 Little-Endian임을 나타냅니다. 따라서 "ZERO WIDTH NO-break SPACE" 문자를 BOM이라고도 합니다.
UTF-8에서는 바이트 순서를 나타내기 위해 BOM이 필요하지 않지만 BOM을 사용하여 인코딩 방법을 나타낼 수 있습니다. "ZERO WIDTH NO-breakspace" 문자의 UTF-8 인코딩은 EF BB BF입니다(독자는 앞서 소개한 인코딩 방법을 사용하여 이를 확인할 수 있습니다). 따라서 수신기가 EF BBBF로 시작하는 바이트 스트림을 수신하면 UTF-8로 인코딩되었음을 알 수 있습니다.
Windows는 BOM을 사용하여 텍스트 파일의 인코딩을 표시합니다.
6. 추가 참고 자료 이 기사의 주요 참고 자료는 "ISO-IEC 10646 및 유니코드에 대한 간략한 개요"( http://www.nada.kth.se/i18n/ucs/unicode-iso10646-oview.html )입니다.
또한 좋아 보이는 두 가지 정보를 찾았지만 초기 질문에 대한 답을 이미 알고 있었기 때문에 읽지 않았습니다.
"유니코드 이해 유니코드 표준에 대한 일반 소개"( http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&item_id=IWS-Chapter04a )
"문자 세트 인코딩 기본 문자 세트 인코딩 및 레거시 인코딩 이해"( http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&item_id=IWS-Chapter03 )
Windows API를 사용하는 버전과 Windows API를 사용하지 않는 버전을 포함하여 UTF-8, UCS-2 및 GBK를 서로 변환하기 위한 소프트웨어 패키지를 작성했습니다. 앞으로 시간이 된다면 정리해서 개인 홈페이지( http://fmddlmyy.home4u.china.com )에 올려보도록 하겠습니다.
모든 문제를 고민한 후에 이 글을 쓰기 시작했는데, 시간이 지나면 끝낼 수 있을 것 같았습니다. 의외로 문구를 고려하고 내용을 확인하는 데 시간이 오래 걸려서 오후 1시 30분부터 9시까지 썼습니다. 일부 독자들이 이로부터 혜택을 받을 수 있기를 바랍니다.
부록 1 위치 코드, GB2312, 내부 코드 및 코드 페이지에 대해 이야기해 보겠습니다. 일부 친구는 기사에서 이 문장에 대해 여전히 질문을 가지고 있습니다.
"GB2312의 원본 텍스트는 여전히 지역 코드입니다. 지역 코드에서 내부 코드까지 각각 상위 바이트와 하위 바이트에 A0을 추가해야 합니다."
자세히 설명하겠습니다.
"GB2312의 원문"은 1980년 국가 표준인 "중화인민공화국 국가 표준 정보 교환을 위한 한자 코드 문자 집합 기본 집합 GB2312-80"을 가리킨다. 이 표준은 한자와 한자 기호를 인코딩하기 위해 두 개의 숫자를 사용합니다. 첫 번째 숫자를 "영역"이라고 하고 두 번째 숫자를 "비트"라고 합니다. 그래서 위치코드라고도 합니다. 영역 1-9는 중국어 기호이고, 영역 16-55는 1급 한자이며, 영역 56-87은 2급 한자입니다. 이제 Windows에는 위치 입력 방법도 있습니다. 예를 들어 "ah"를 얻으려면 1601을 입력하세요. (이 위치 입력 방법은 16진수 GB2312와 10진수 위치 코드를 자동으로 인식하므로 B0A1을 입력해도 "ah"가 표시됩니다.)
내부 코드는 운영 체제 내의 문자 인코딩을 나타냅니다. 초기 운영 체제의 내부 코드는 언어에 따라 다릅니다. 오늘날의 Windows는 시스템 내에서 유니코드를 지원하며 코드 페이지를 사용하여 다양한 언어에 적응합니다. "내부 코드"라는 개념은 비교적 모호합니다. Microsoft에서는 일반적으로 기본 코드 페이지에 지정된 인코딩을 내부 코드라고 부릅니다.
내부 코드라는 용어에 대한 공식적인 정의는 없으며, 코드 페이지는 단지 Microsoft라는 회사의 이름일 뿐입니다. 프로그래머로서 우리가 그것이 무엇인지 아는 한 이러한 용어를 너무 많이 조사할 필요는 없습니다.
소위 코드 페이지(코드 페이지)는 언어에 대한 문자 인코딩입니다. 예를 들어, GBK의 코드 페이지는 CP936이고, BIG5의 코드 페이지는 CP950이며, GB2312의 코드 페이지는 CP20936입니다.
Windows에는 기본 코드 페이지, 즉 문자를 해석하기 위해 기본적으로 사용되는 인코딩이라는 개념이 있습니다. 예를 들어 Windows 메모장은 텍스트 파일을 열고 내부 콘텐츠는 BA, BA, D7, D6과 같은 바이트 스트림입니다. Windows는 이를 어떻게 해석해야 합니까?
유니코드 인코딩, GBK, BIG5 또는 ISO8859-1에 따라 해석해야 합니까? GBK로 해석하면 "한자"라는 단어가 나옵니다. 다른 인코딩 해석에 따르면 해당 문자를 찾을 수 없거나, 잘못된 문자를 찾을 수도 있습니다. 소위 "오류"는 텍스트 작성자의 원래 의도와 일치하지 않으며 왜곡된 문자가 생성되는 것을 의미합니다.
대답은 Windows가 현재 기본 코드 페이지에 따라 텍스트 파일의 바이트 스트림을 해석한다는 것입니다. 기본 코드 페이지는 제어판의 국가별 옵션을 통해 설정할 수 있습니다. 메모장의 다른 이름으로 저장에 ANSI 항목이 있는데, 기본 코드 페이지의 인코딩 방식에 따라 실제로 저장됩니다.
Windows의 내부 코드는 유니코드이며 기술적으로 동시에 여러 코드 페이지를 지원할 수 있습니다. 파일이 사용하는 인코딩을 설명할 수 있고 사용자가 해당 코드 페이지를 설치했다면 Windows는 이를 올바르게 표시할 수 있습니다. 예를 들어 HTML 파일에 문자 세트를 지정할 수 있습니다.
일부 HTML 파일 작성자, 특히 영어 작성자는 전 세계 모든 사람이 영어를 사용하고 파일에 문자 세트를 지정하지 않는다고 믿습니다. 0x80-0xff 사이의 문자를 사용하고 중국어 Windows가 기본 GBK에 따라 이를 해석하는 경우 잘못된 문자가 나타납니다. 이때 html 파일에 charset을 지정하는 문을 추가하면 됩니다. 예를 들면 다음과 같습니다.
<meta http-equiv="Content-Type" content="text/html; charset=ISO8859-1">
원저작자가 사용한 코드 페이지가 ISO8859-1과 호환된다면 문자가 깨지는 일은 없을 것입니다.
아씨의 위치코드는 1601로 16진수로는 0x10, 0x01입니다. 이는 컴퓨터에서 널리 사용되는 ASCII 인코딩과 충돌합니다. 00-7f의 ASCII 인코딩과 호환되도록 지역 코드의 상위 바이트와 하위 바이트에 각각 A0을 추가합니다. 이렇게 하면 "ah"에 대한 코드는 B0A1이 됩니다. 또한 GB2312 인코딩으로 두 개의 A0이 추가된 인코딩을 호출하지만 GB2312의 원본 텍스트에는 이에 대한 언급이 전혀 없습니다.