IANA 문자 집합 레지스트리
고친 사람 github-actions[bot]
IANA 문자 집합 레지스트리는 문자 인코딩마다 공식 이름을 정해 줍니다.
웹 서버가 응답에 적는 charset=utf-8 의 utf-8 이 이 목록에 오른 이름입니다.
보내는 쪽과 받는 쪽은 이 이름 덕분에 같은 규칙으로 바이트를 읽습니다.
한 인코딩을 부르는 여러 이름도 이 목록이 한 항목으로 묶어 둡니다.
쉽고 빠른 이해
인코딩 이름을 모아 둔 공식 명단입니다. utf-8 · euc-kr · iso-8859-1 같은 이름이 모두
여기 올라 있습니다.
이 명단이 없으면 같은 인코딩을 저마다 다른 이름으로 부르게 됩니다. 받는 쪽이 모르는 이름이 오면 본문을 못 읽습니다. 엉뚱한 규칙으로 읽으면 글자가 깨집니다.
- 등록하려는 쪽이 이름을 정해 공개 검토에 올립니다
- 검토를 통과하면 명단에 대표 이름 · 별칭 · 번호가 한 항목으로 오릅니다
- 서버와 라이브러리는 이 명단의 이름을 알아듣도록 만들어집니다
명단에 올랐다고 그 인코딩을 쓰라는 뜻은 아닙니다. 등록은 이름과 인코딩의 짝을 적어 둘 뿐입니다. 그래서 낡은 인코딩도 나란히 올라 있습니다.
브라우저는 이 명단을 따르지 않습니다. 브라우저 제작사들이 따로 정한, 이름과 인코딩의 짝
목록으로 헤더를 읽습니다. 그래서 같은 이름을 서버와 브라우저가 다른 인코딩으로 읽는 일이
생깁니다. 헤더에 utf-8 을 적으면 두 쪽이 같은 인코딩으로 읽습니다.
상세
이 절은 레지스트리를 네 대목으로 풉니다. 인코딩 이름이 왜 필요한지, 한 항목에 무엇이 적히는지, 이름이 어떻게 등록되는지, 그리고 코드와 브라우저가 이 이름을 어떻게 받는지입니다.
인코딩 이름이 필요한 까닭
컴퓨터는 글자를 바이트로 바꿔 저장하고 보냅니다. 글자를 바이트로 적는 규칙이 문자 인코딩입니다.
같은 「한」도 UTF-8(Unicode Transformation Format 8-bit, 유니코드 변환 형식 8비트)로 적으면
ED 95 9C 세 바이트입니다. EUC-KR(Extended Unix Code for Korean, 한국어 확장 유닉스 코드)로
적으면 C7 D1 두 바이트입니다. 이 문서의 바이트 값은 모두 십육진수입니다.
그래서 바이트를 받는 쪽은 어느 규칙으로 적었는지 알아야 글자로 되돌릴 수 있습니다. HTTP
(HyperText Transfer Protocol) 응답은 이 규칙을 Content-Type 헤더에 적어 알립니다.
Content-Type: text/html; charset=utf-8
charset= 뒤의 값이 인코딩의 이름입니다. 이 값을 charset 매개변수라고
부릅니다.
Content-Type 헤더는 MIME(Multipurpose Internet Mail Extensions, 다목적 인터넷 메일 확장)에서
왔습니다. MIME 은 전자메일에 글 말고도 그림과 파일을 담으려고 만든 규칙입니다. HTTP 가 본문의
종류를 알릴 때 이 규칙을 빌려 씁니다.
이 값은 보내는 쪽과 받는 쪽이 미리 아는 이름이어야 합니다. 보내는 쪽이 지어낸 이름은 받는 쪽이 알아듣지 못합니다. 그 약속된 이름을 한곳에 모아 둔 것이 이 레지스트리입니다.
IANA 와 레지스트리
IANA(Internet Assigned Numbers Authority, 인터넷 할당 번호 관리 기관)는 인터넷 프로토콜이 쓰는 번호와 이름을 배정하고 공개하는 기관입니다. 포트 번호와 HTTP 상태 코드 목록도 이 기관이 관리합니다.
레지스트리는 값과 그 뜻을 짝지어 모아 둔 공개 목록입니다. 누구나 읽을 수 있습니다. 한 값이 두 뜻을 갖지 않게 관리됩니다. IANA 는 이런 목록을 프로토콜마다 여럿 둡니다.
문자 집합 레지스트리는 그중 인코딩 이름을 모은 목록입니다. 영어 이름은 Character Sets 입니다.
이름에는 「문자 집합(charset)」이 들어 있습니다. 그런데 이 목록이 다루는 것은 인코딩입니다. 이 목록에서 문자 집합은 글자 목록과 그 글자를 바이트로 적는 규칙을 한데 묶어 부르는 말입니다. 실무에서 인코딩이라고 부르는 것과 같은 대상입니다.
한 항목의 생김새
항목 하나는 인코딩 하나입니다. 아래 표는 두 인코딩의 항목을 칸별로 옮긴 것입니다. 하나는 서유럽 언어용 인코딩인 ISO-8859-1 입니다. 이름의 ISO 는 국제 표준화 기구(International Organization for Standardization)를 가리킵니다. 다른 하나는 앞에서 본 한국어 인코딩 EUC-KR 입니다.
| 칸 | 담는 것 | ISO-8859-1 항목 | EUC-KR 항목 |
|---|---|---|---|
| Name | 대표 이름 | ISO_8859-1:1987 |
EUC-KR |
| Preferred MIME Name | MIME 헤더에 적기를 권하는 이름 | ISO-8859-1 |
EUC-KR |
| MIBenum | 이름 대신 쓰는 정수 번호 | 4 | 38 |
| Aliases | 같은 인코딩을 가리키는 다른 이름 | latin1 · l1 · csISOLatin1 외 다섯 |
csEUCKR |
표를 보면 한 인코딩의 이름이 여러 칸에 흩어져 있습니다. 한 인코딩에 이름이 하나뿐인 경우는 드뭅니다. 각 칸이 무엇인지는 아래 소절들이 하나씩 풉니다.
대표 이름과 별칭
ISO-8859-1 은 대표 이름 ISO_8859-1:1987 말고도 latin1 · l1 · csISOLatin1 로 불립니다.
한 인코딩이 이름을 여럿 갖는 까닭은 여러 표준 기구와 회사가 같은 인코딩을 따로 불러 왔기
때문입니다. 레지스트리는 이 이름들을 하나로 줄이지 않습니다. 대표 이름을 하나 정하고 나머지를
별칭으로 붙입니다.
규칙은 하나입니다. 한 이름은 반드시 한 인코딩만 가리킵니다. 그래서 별칭 가운데 어느 것을 받아도 가리키는 항목은 하나로 정해집니다.
이름은 대소문자를 가리지 않습니다. LATIN1 과 latin1 은 같은 이름입니다.
flowchart TD
A["latin1"] --> E["ISO_8859-1:1987 항목"]
B["LATIN1"] --> E
C["ISO-8859-1"] --> E
D["csISOLatin1"] --> E
E --> F["MIBenum 4"]
위 그림은 이름 넷이 한 항목으로 모이는 모습입니다. 항목에 매긴 번호는 하나뿐입니다.
헤더에 적는 이름
대표 이름이 MIME 헤더에 쓰기 불편한 모양일 때가 있습니다. ISO_8859-1:1987 처럼 연도가 붙은
이름이 그렇습니다. 그럴 때는 헤더에 적기를 권하는 이름이 따로 붙습니다. 표의 Preferred MIME Name
칸이 그 이름입니다.
ISO-8859-1 항목에서는 이 칸이 ISO-8859-1 입니다. 헤더에는 이 칸의 이름을 적습니다. 이 칸이
비어 있는 인코딩이면 대표 이름을 적습니다. EUC-KR 처럼 대표 이름을 헤더에 그대로 적을 수 있는
인코딩은 두 칸이 같습니다.
MIBenum 과 cs 로 시작하는 별칭
MIB(Management Information Base, 관리 정보 베이스)는 네트워크 장비에서 원격으로 읽을 수 있는 항목을 미리 정의해 둔 모음입니다. 관리 도구는 이 정의를 보고 장비의 상태를 읽습니다.
프린터용 MIB 도 있습니다. 여기서는 프린터가 쓰는 인코딩을 이름 대신 정수로 알립니다. 그 정수가 MIBenum 입니다.
MIBenum 은 인코딩마다 하나씩, 겹치지 않게 매겨집니다. 번호는 IANA 가 등록 때 배정합니다. 등록을 신청한 쪽이 고르지 않습니다.
번호 몇 개를 보면 이렇습니다. 영어 알파벳과 숫자만 담는 US-ASCII(American Standard Code for Information Interchange, 미국 정보 교환 표준 부호)는 3 입니다. UTF-8 은 106 입니다.
MIBenum 마다 cs 로 시작하는 별칭이 하나씩 붙습니다. 이 별칭은 Aliases 칸에 들어갑니다.
MIB 쪽에서는 이 별칭을 번호의 이름으로 씁니다.
따로 정하지 않으면 IANA 가 대표 이름 앞에 cs 를 붙여 만듭니다. csUTF8 · csEUCKR 이
그렇게 생긴 별칭입니다.
HTTP 헤더에는 번호가 아니라 이름을 적습니다. 백엔드 코드에서 MIBenum 을 만나는 것은 이런 관리 규격을 다룰 때입니다.
목록에 이름이 오르는 과정
새 이름이 목록에 오르려면 먼저 자격을 갖춰야 합니다. 다른 표준 기구나 회사가 이미 정의한 인코딩만 올립니다. 그 정의는 누구나 읽을 수 있는 문서로 반드시 공개돼 있어야 합니다. 이 레지스트리는 새 인코딩을 설계하는 곳이 아닙니다.
자격을 갖춘 등록안이 올라가서 목록에 오르기까지는 아래와 같습니다.
sequenceDiagram
participant 신청자
participant 메일링 리스트
participant 검토자
participant IANA
신청자->>메일링 리스트: 등록안을 올린다
Note over 메일링 리스트: 2주 동안 공개 검토
신청자->>검토자: 등록을 신청한다
검토자->>메일링 리스트: 승인 여부를 2주 안에 알린다
Note over 검토자: 거절되면 여기서 끝난다
검토자->>IANA: 승인된 등록안
IANA->>IANA: 등록하고 MIBenum 을 배정한다
신청자는 등록안을 전용 메일링 리스트에 올립니다. 그때부터 2주 동안 누구나 정의와 이름에 의견을 낼 수 있습니다.
그 뒤 신청자가 검토자에게 등록을 신청합니다. 검토자 한 사람이 2주 안에 승인 여부를 알립니다. 승인된 이름은 IANA 가 번호를 매겨 목록에 올립니다.
등록이 끝나기 전의 이름은 쓰지 않습니다. 그 사이에는 x- 로 시작하는 이름을 씁니다. x- 는
아직 등록되지 않은 사설 이름이라는 표시입니다.
목록에 올랐다고 그 인코딩을 쓰라는 뜻은 아닙니다. 등록은 이 이름이 이 인코딩을 가리킨다는 기록일 뿐입니다. 그래서 오래된 인코딩과 쓰임이 좁은 인코딩도 나란히 올라 있습니다.
코드에서 이 이름을 받는 방식
백엔드 코드는 이름 문자열로 인코딩을 고릅니다. 자바의 Charset 클래스가 그 예입니다.
Charset.forName 에 이름을 넘기면 그 인코딩을 다루는 객체가 돌아옵니다.
자바는 인코딩마다 표준 이름(canonical name)을 하나 둡니다. name() 이 돌려주는 이름입니다.
레지스트리에 오른 인코딩이면 레지스트리의 헤더용 이름(Preferred MIME Name)을 가져다 표준
이름으로 씁니다. 나머지 이름은 별칭으로 받아 줍니다.
var cs = Charset.forName("latin1");
cs.name(); // "ISO-8859-1"
첫 줄은 별칭 latin1 로 인코딩을 찾습니다. 둘째 줄이 돌려주는 표준 이름은 대표 이름
ISO_8859-1:1987 이 아니라 헤더용 이름 ISO-8859-1 입니다.
브라우저가 따르는 이름표 목록
WHATWG(Web Hypertext Application Technology Working Group, 웹 하이퍼텍스트 애플리케이션 기술 작업반)는 브라우저 제작사들이 웹 표준을 함께 쓰는 모임입니다. 브라우저가 공통으로 따를 규칙을 이 모임이 문서로 냅니다.
브라우저는 헤더의 이름을 이 레지스트리대로 읽지 않습니다. WHATWG 가 낸 Encoding Standard를 따릅니다. 이 문서에 브라우저가 알아듣는 이름과 그 이름이 가리키는 인코딩이 적혀 있습니다.
브라우저가 알아듣는 이름을 이름표(label)라고 부릅니다. 이름표마다 가리키는 인코딩이 하나씩 정해져 있습니다. 몇몇 이름표는 IANA 와 다른 인코딩으로 묶입니다.
어긋나는 이름표는 두 인코딩 둘레에 모여 있습니다. 하나는 Windows-1252 입니다.
ISO-8859-1 에 글자 몇 개를 더 얹은 서유럽 인코딩입니다. iso-8859-1 이라고 적고 windows-1252
바이트를 보낸 옛 웹 페이지가 많았습니다. 브라우저는 그런 페이지를 깨지지 않게 읽으려고 넓은
쪽으로 읽습니다.
us-ascii 라고 적힌 페이지도 브라우저는 windows-1252 로 읽습니다. windows-1252 는 ASCII 의
바이트를 모두 같은 글자로 읽습니다. 그래서 ASCII 밖의 바이트가 섞여 와도 깨지지 않습니다.
다른 하나는 CP949(Code Page 949, 코드 페이지 949)입니다. 마이크로소프트가 EUC-KR 에 한글
글자를 더 얹은 확장입니다. windows-949 라는 이름으로도 부릅니다. 브라우저의 EUC-KR 은 이 확장이
더한 한글까지 읽습니다.
ks_c_5601-1987 은 한국 표준 문자 집합 KS C 5601(KS 는 Korean Industrial
Standards, 한국산업표준)을 가리키는 이름입니다. 레지스트리에서는 EUC-KR 과 별개 항목입니다.
브라우저는 이 이름도 EUC-KR 로 읽습니다.
| 헤더에 적힌 이름 | IANA 레지스트리에서 | 브라우저에서 |
|---|---|---|
iso-8859-1 |
ISO-8859-1 | windows-1252 |
us-ascii |
US-ASCII | windows-1252 |
ks_c_5601-1987 |
KS_C_5601-1987 (EUC-KR 과 다른 항목) | EUC-KR |
windows-949 |
목록에 없음 | EUC-KR |
위 두 줄은 서유럽 이름이 넓은 쪽으로 읽히는 경우입니다. 아래 두 줄은 한국어 이름이 브라우저에서
EUC-KR 하나로 모이는 경우입니다. 서버 쪽 라이브러리의 EUC-KR 은 CP949 가 더한 글자를 모를 수
있습니다. 그러면 같은 euc-kr 을 두고 서버와 브라우저가 다른 글자 범위를 읽습니다.
서버 코드가 이름으로 인코딩을 고를 때는 이 레지스트리의 이름이 기준입니다. 그 응답을 브라우저가
읽을 때는 브라우저 쪽 이름표 규칙으로 해석됩니다. utf-8 은 두 목록이 같은 인코딩으로 읽는
이름입니다. 브라우저 쪽 규격은 새로 만드는 웹 문서에 UTF-8 만 쓰게 합니다.
관련 항목
이 레지스트리를 관리하는 기관과 규정 문서
IANA · IETF · RFC 2978 · RFC 2046 · 프로토콜 파라미터 · 레지스트리
이 레지스트리가 이름을 붙이는 대상
문자 인코딩 · 문자 집합 · Unicode · 코드 포인트
이 레지스트리에 오른 인코딩
UTF-8 · UTF-16 · UTF-32 · ASCII · ISO-8859-1 · EUC-KR · ISO-2022-KR · KSC-5601 · Shift_JIS
이 레지스트리의 이름을 적는 헤더와 선언
Content-Type · Content-Type charset · meta charset · MIME · XML 선언
이 레지스트리와 다르게 이름을 묶는 브라우저 규격
WHATWG · WHATWG Encoding Standard · Windows-1252 · CP949 · 인코딩 스니핑 알고리즘
이름 대신 번호로 인코딩을 가리키는 관리 규격
MIB · SNMP · Printer MIB · MIBenum
이 이름으로 인코딩을 고르는 라이브러리
이름이 어긋나면 생기는 글자 깨짐
다른 이름: Character Sets · IANA Character Sets · IANA charset registry · 문자 집합 레지스트리