ASCII
고친 사람 github-actions[bot]
ASCII 는 영어 글자와 숫자, 기호를 컴퓨터끼리 같은 수로 주고받게 해 주는 약속입니다. 글자 128개에 0부터 127까지 번호를 하나씩 붙이고, 그 번호를 바이트 하나에 담아 보냅니다. 유니코드도 첫 128개 번호를 이 표에서 바꾸지 않고 가져왔습니다. 그래서 오늘 쓰는 텍스트 파일과 통신 규약 아래에도 이 표가 깔려 있습니다.
쉽고 빠른 이해
ASCII 는 영어 글자 하나를 0부터 127 사이의 번호 하나로 바꾸는 표입니다. 대문자 A 는 65번, 소문자 a 는 97번, 숫자 글자 0 은 48번입니다.
컴퓨터가 다루는 것은 수뿐입니다. 글자를 주고받으려면 어느 글자를 몇 번으로 적을지 보내는 쪽과 받는 쪽이 미리 맞춰 두어야 합니다. 이 약속이 없으면 같은 바이트를 서로 다른 글자로 읽습니다.
어떻게 도나:
- 보내는 쪽이 적을 글자의 번호를 표에서 찾습니다
- 그 번호를 바이트 하나에 담습니다
- 받는 쪽은 바이트 값을 같은 표에서 찾아 글자로 되돌립니다
대가는 담는 글자가 영어 알파벳과 숫자, 기호뿐이라는 점입니다. 한글도 악센트가 붙은 유럽 글자도 이 표에 없습니다. 128 이상의 바이트 값은 표가 정하지 않아서 프로그램마다 다르게 읽습니다.
상세
ASCII 의 본체는 128칸짜리 부호표 하나입니다. 아래는 그 표를 놓고 짜임과 무리와 번호 순서를 차례로 따라갑니다. 표가 어떻게 짜였는지, 칸이 어느 무리로 나뉘는지, 글자 번호가 어떤 순서로 놓였는지입니다.
마지막은 일곱 비트짜리 번호가 여덟 비트 바이트에 담기는 방법입니다.
이름과 표의 크기
ASCII 는 American Standard Code for Information Interchange 의 줄임말입니다. 우리말로 옮기면 미국 정보 교환 표준 부호입니다. 「애스키」라고 읽습니다. 서로 다른 정보 처리 시스템과 통신 장비가 글자를 주고받을 때 쓰라고 만든 표입니다.
글자 하나에 비트 조합 하나를 일대일로 짝지은 규칙을 부호화 문자 집합(coded character set)이라고 부릅니다. 실무에서는 흔히 문자 인코딩이라고 부릅니다. ASCII 는 그런 규칙 가운데 하나입니다. 대문자 K 라면 비트 조합 1001011 이 짝입니다.
비트는 0 이나 1 하나를 담는 가장 작은 단위입니다. 비트 여덟을 묶은 단위가 바이트입니다. ASCII 의 비트 조합은 일곱 비트입니다. 왼쪽부터 b7 · b6 · b5 · b4 · b3 · b2 · b1 이라고 부릅니다. 각 비트에 64 · 32 · 16 · 8 · 4 · 2 · 1 의 무게를 주면 조합 하나가 0 부터 127 사이의 정수 하나가 됩니다. 그래서 표의 칸은 모두 128개입니다.
K 의 1001011 은 64 + 8 + 2 + 1 이라 75 입니다.
열과 행으로 짠 표
128칸은 8열 16행의 표로 놓입니다. 앞 세 비트 b7 · b6 · b5 가 열 번호 0~7 을 정하고, 뒤 네 비트 b4 · b3 · b2 · b1 이 행 번호 0~15 를 정합니다. 칸을 가리킬 때는 「열/행」 꼴로 적습니다. K 는 열 4, 행 11 이라 4/11 입니다.
이 표기는 십육진수와 바로 맞물립니다. 행이 16개라서 열 번호가 십육진수의 앞 숫자, 행 번호가 뒤 숫자가 됩니다. 4/11 은 십육진수로 4B 이고 십진수로 75 입니다. 앞으로 바이트 값은 4B 같은 십육진수 두 글자로 적습니다.
표 전체는 이렇습니다. 위 칸이 열 번호, 왼쪽 칸이 행 번호입니다.
| 행 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|---|
| 0 | NUL |
DLE |
SP |
0 |
@ |
P |
` |
p |
| 1 | SOH |
DC1 |
! |
1 |
A |
Q |
a |
q |
| 2 | STX |
DC2 |
" |
2 |
B |
R |
b |
r |
| 3 | ETX |
DC3 |
# |
3 |
C |
S |
c |
s |
| 4 | EOT |
DC4 |
$ |
4 |
D |
T |
d |
t |
| 5 | ENQ |
NAK |
% |
5 |
E |
U |
e |
u |
| 6 | ACK |
SYN |
& |
6 |
F |
V |
f |
v |
| 7 | BEL |
ETB |
' |
7 |
G |
W |
g |
w |
| 8 | BS |
CAN |
( |
8 |
H |
X |
h |
x |
| 9 | HT |
EM |
) |
9 |
I |
Y |
i |
y |
| 10 | LF |
SUB |
* |
: |
J |
Z |
j |
z |
| 11 | VT |
ESC |
+ |
; |
K |
[ |
k |
{ |
| 12 | FF |
FS |
, |
< |
L |
\ |
l |
| |
| 13 | CR |
GS |
- |
= |
M |
] |
m |
} |
| 14 | SO |
RS |
. |
> |
N |
^ |
n |
~ |
| 15 | SI |
US |
/ |
? |
O |
_ |
o |
DEL |
제어 문자와 보이는 글자
128칸은 두 무리로 나뉩니다. 첫째 무리는 제어 문자입니다. 화면에 그려지는 모양 없이, 받는 장치에 무엇을 하라고 시키는 번호입니다.
둘째 무리는 손으로 쓰거나 찍어 내는 모양이 있는 보이는 글자입니다. 표준 용어로는 도형 문자(graphic character)라고 부릅니다. 둘 사이에 공백과 DEL 이 하나씩 끼어 있습니다.
| 칸 | 바이트 | 십진수 | 무엇이 들었나 |
|---|---|---|---|
| 열 0 · 열 1 | 00 ~ 1F |
0 ~ 31 | 제어 문자 32개 |
2/0 |
20 |
32 | 공백 SP |
2/1 ~ 7/14 |
21 ~ 7E |
33 ~ 126 | 보이는 글자 94개 |
7/15 |
7F |
127 | DEL |
공백 SP(Space)는 보이는 글자로 칩니다. 모양이 없는 것이 그 글자의 모양입니다. 낱말을 가르는 데 쓰고, 인쇄 위치를 한 칸 앞으로 옮기는 일도 합니다.
제어 문자 서른둘 가운데 스물에는 하는 일을 적은 이름이 붙어 있습니다. 통신을 돕는 통신 제어(Communication Control) 열 개, 인쇄 위치를 옮기는 서식 지정(Format Effector) 여섯 개, 데이터를 논리적으로 나누는 정보 구분(Information Separator) 네 개입니다. 나머지 열두 개에는 이 이름이 안 붙습니다. 자주 만나는 것을 추리면 이렇습니다.
| 이름 | 바이트 | 묶음 | 하는 일 |
|---|---|---|---|
NUL(Null) |
00 |
없음 | 비트가 모두 0 인 글자. 시간이나 매체의 빈 곳을 채우는 데 쓸 수 있습니다 |
BEL(Bell) |
07 |
없음 | 사람의 주의를 불러야 할 때 씁니다. 경보 장치를 울릴 수 있습니다 |
BS(Backspace) |
08 |
서식 지정 | 인쇄 위치를 같은 줄에서 한 칸 뒤로 옮깁니다 |
HT(Horizontal Tabulation) |
09 |
서식 지정 | 인쇄 위치를 미리 정해 둔 다음 칸으로 옮깁니다 |
LF(Line Feed) |
0A |
서식 지정 | 인쇄 위치를 다음 줄로 옮깁니다 |
CR(Carriage Return) |
0D |
서식 지정 | 인쇄 위치를 같은 줄의 맨 앞으로 옮깁니다 |
ESC(Escape) |
1B |
없음 | 뒤따르는 몇 글자의 해석을 바꿉니다. 표에 없는 글자를 들일 때 씁니다 |
정의가 프린터를 기준으로 쓰여 있어서 「인쇄 위치」가 주어입니다. 화면 장치에도 같이 적용됩니다.
맨 끝 7F 의 DEL(Delete)은 엄밀히는 제어 문자가 아닙니다. 일곱 비트가 모두 1 인 값입니다. 천공 테이프에서 잘못 뚫은 글자를 지우는 데 썼습니다. DEL 도 NUL 처럼 매체나 시간의 빈 곳을 채우는 데 쓸 수 있습니다.
글자 번호가 놓인 순서
표를 열 단위로 보면 같은 무리의 글자가 이어진 번호에 모여 있습니다.
| 글자 | 칸 | 바이트 | 십진수 |
|---|---|---|---|
0 ~ 9 |
3/0 ~ 3/9 |
30 ~ 39 |
48 ~ 57 |
A ~ Z |
4/1 ~ 5/10 |
41 ~ 5A |
65 ~ 90 |
a ~ z |
6/1 ~ 7/10 |
61 ~ 7A |
97 ~ 122 |
숫자 글자는 열 3 에 있고, 행 번호가 곧 그 숫자의 값입니다. 글자 7 은 3/7 이라 바이트 37 입니다.
대문자와 소문자는 같은 행에 있고 열만 둘 차이 납니다. A 는 4/1, a 는 6/1 입니다. 열 4 는 비트로 100, 열 6 은 110 이라 b6 하나만 다릅니다. b6 의 무게가 32 이므로 대문자와 소문자의 번호는 26쌍 모두 32 차이 납니다.
번호를 정렬 기준으로 쓸 때는 이진 값이 순서를 정합니다. 대문자 26개가 모두 소문자보다 앞에 섭니다. Z(90)가 a(97)보다 앞입니다.
여덟 비트 바이트에 담기
ASCII 를 네트워크로 보낼 때는 일곱 비트 번호를 여덟 비트 바이트 하나에 담고 맨 앞 비트를 0 으로 둡니다. 호스트 사이 연결에 ASCII 를 쓰자고 한 제안이 이 방법입니다. 메일 전송 규약도 같은 방법을 씁니다.
packet-beta 0: "늘 0" 1-3: "열 번호 (b7 b6 b5)" 4-7: "행 번호 (b4 b3 b2 b1)"
그림 위의 0~7 은 바이트 안의 비트 자리 번호입니다. b7 부터 b1 까지는 비트의 무게에 붙인 이름이라 세는 방향이 반대입니다.
그래서 ASCII 바이트의 값은 00 에서 7F 까지입니다. K 라면 맨 앞 0 뒤에 열 100 과 행 1011 이 붙어 01001011, 곧 4B 입니다.
전송 중 오류를 어떻게 잡을지는 ASCII 가 정하지 않습니다. 부호를 물리 매체에 적는 법과 오류 검사는 다른 표준에 맡겼습니다.
표현 한계
앞 절의 128칸 표와 그 표로 적은 바이트열을 놓고, 무엇을 못 담는지 짚습니다. 먼저 에러 없이 글자만 바뀌는 것입니다.
그다음이 표에 칸이 없는 글자, 줄바꿈, 제어 문자처럼 표가 정하지 않고 남겨 둔 것입니다.
바이트열에 없는 변형 이름
ISO 646 은 국제 표준화 기구 ISO(International Organization for Standardization)가 낸 7비트 문자 집합 표준입니다. ASCII 와 같은 128칸 틀을 쓰지만, 그 가운데 12칸을 나라나 용도에 맞게 채울 수 있게 열어 두었습니다. 이렇게 채워 완성한 표 하나하나를 변형이라고 부릅니다. 변형은 같은 표준 문서 안에서 열린 12칸을 다르게 채운 표입니다. 아래 「갈래」 절에 나오는 「판」은 다른 것을 가리킵니다 — 판은 표준 문서가 개정된 세대입니다.
| 칸 | 바이트 | ASCII 글자 | 변형이 고를 수 있는 것 |
|---|---|---|---|
2/3 · 2/4 |
23 · 24 |
# · $ |
정해진 두 글자 가운데 하나. # 대신 £, $ 대신 통화 기호 ¤ |
4/0 · 5/11~5/14 · 6/0 · 7/11~7/14 |
40 · 5B~5E · 60 · 7B~7E |
@ [ \ ] ^ ` { | } ~ |
나라나 용도에 맞는 글자 하나. 또는 쓰지 않는다고 선언 |
바이트열에는 어느 변형으로 적었는지가 안 실립니다. 보낸 쪽이 고른 변형을 받는 쪽도 알 수 있어야 한다는 것까지만 정합니다. 그것을 알리는 길은 표준 밖에 두었습니다. 주고받는 쪽에 합의가 없으면 기준 변형인 IRV(International Reference Version, 국제 기준 변형)로 읽기로 되어 있습니다. 받는 쪽이 다른 변형으로 읽으면 에러 없이 다른 글자가 보입니다.
바이트 5C 하나가 미국 표로는 \, 한국 변형으로는 ₩, 일본 변형으로는 ¥ 입니다. 보내는 쪽과 받는 쪽이 고른 변형이 어긋나면 이렇게 됩니다.
sequenceDiagram
participant 보낸쪽
participant 받는쪽
Note over 보낸쪽: 한국 변형으로 적는다
보낸쪽->>받는쪽: 바이트 5C 하나
Note over 받는쪽: 미국 표로 읽는다
Note over 보낸쪽,받는쪽: 바이트는 바뀌지 않았는데 글자가 ₩ 에서 역슬래시로 바뀐다
ASCII 도 이 언저리의 # @ [ \ ] ^ ` { | } ~ 는 주고받는 쪽이 합의했는지 확인하기 전에는 국제 교환에 쓰지 말라고 권합니다.
128 이상의 바이트 값
ASCII 가 짝을 정한 바이트는 00 에서 7F 까지입니다. 맨 앞 비트가 1 인 80 에서 FF 까지 128개에는 아무 글자도 짝짓지 않았습니다.
정하지 않은 값을 받으면 소프트웨어마다 다르게 읽습니다. 웹 브라우저는 「ascii」라는 이름을 받으면 windows-1252 라는 다른 표로 읽습니다. windows-1252 는 ASCII 와 ISO 8859-1 의 글자를 모두 품는 8비트 표입니다. 그래서 바이트 80 을 「ASCII 로 읽어라」라는 요청에도 유로 기호 € 로 읽습니다. 「latin1」이라는 이름도 같은 표를 가리키는 것으로 다룹니다 — latin1 은 본래 ISO 8859-1 의 딴이름입니다.
에러를 내는 쪽도 있습니다. 아래 「예시」 절의 파이썬 ascii 코덱이 그렇습니다. 바이트 값을 같은 번호의 글자에 그대로 짝짓는 방식을 쓰는 쪽도 있습니다.
라틴 문자 밖의 글자
보이는 글자 94개는 숫자 10개, 라틴 알파벳 대소문자 52개, 그리고 문장 부호와 기호 32개입니다. 이 문자 집합은 라틴 문자를 쓰는 알파벳에 맞춘 것입니다. 한글과 한자, 그리스 글자와 키릴 글자는 칸이 없습니다.
é 처럼 악센트가 붙은 글자도 칸이 없습니다. 우회로는 두 글자를 한 칸에 겹쳐 찍는 것입니다. 글자, BS, 악센트 기호를 차례로 보내면 두 글자가 같은 위치에 찍힙니다. e, BS, ' 를 보내면 é 처럼 찍힙니다.
이 우회로는 표가 é 를 담은 것이 아니라 세 바이트를 겹쳐 찍은 것입니다. 위쪽 128칸까지 쓰는 8비트 표 가운데 라틴 알파벳 1번부터 4번까지(ISO 8859-1 ~ ISO 8859-4)는 BS 나 CR 로 글자를 겹쳐 찍어 합성 글자를 적는 것을 금지합니다.
통화 기호는 $ 하나뿐입니다. ISO 646 은 # 와 $ 칸에 £ 나 ¤ 를 대신 둘 수 있게 했습니다. 따로 합의하지 않았다면 이 기호들은 특정 나라의 통화를 가리키지 않습니다.
표에 없는 글자를 들이는 길은 따로 있습니다. ESC 를 앞세우면 뒤따르는 몇 글자의 해석이 바뀝니다. SO(Shift Out)와 SI(Shift In) 사이의 바이트는 표 밖의 글자 집합으로 읽습니다. 이런 방법을 코드 확장이라고 부르고 절차는 ISO 2022 가 정합니다. ASCII 바이트열이 담는 것은 그 글자가 아니라 다른 표로 넘어가라는 신호입니다.
줄바꿈 표기
줄을 바꾸는 데 쓰는 글자는 둘입니다. CR 은 인쇄 위치를 같은 줄 맨 앞으로, LF 는 다음 줄로 옮깁니다. 두 동작이 갈려 있어서, 줄 하나를 끝내는 바이트를 무엇으로 할지는 표가 하나로 정하지 않습니다.
LF 하나에 「다음 줄 맨 앞으로」라는 뜻을 실을 수도 있습니다. 다만 그렇게 쓰려면 보내는 쪽과 받는 쪽이 합의해야 합니다. 호스트 사이 연결에 ASCII 를 쓰자는 제안도 줄 끝 글자는 받는 쪽 호스트가 정하게 두었습니다. 그때 호스트마다 갈렸습니다. SRI 는 마침표 .(2E)를, UCLA 는 CR(0D)을 줄 끝으로 썼습니다.
지금도 플랫폼마다 줄바꿈을 CR, LF, CR LF 가운데 다른 것으로 적습니다. 텍스트를 다른 인코딩으로 옮길 때 이 글자들은 대개 같은 값으로 넘어갑니다. 유니코드만 다루는 프로그램도 이 문제를 그대로 떠안습니다.
제어 문자의 동작
ASCII 는 제어 문자마다 이름과 번호를 주지만, 받는 장치가 무엇을 할지는 다 정하지 않습니다. FS(File Separator) · GS(Group Separator) · RS(Record Separator) · US(Unit Separator) 넷은 이 순서대로 큰 단위에서 작은 단위로 간다는 계층만 정합니다. 파일 · 그룹 · 레코드 · 단위의 내용과 길이는 정하지 않습니다.
flowchart TD
subgraph 파일["파일 · FS"]
subgraph 그룹["그룹 · GS"]
subgraph 레코드["레코드 · RS"]
단위["단위 · US"]
end
end
end
ISO 646 은 제어 문자의 정의를 제어 기능 표준인 ISO 6429 에 맡깁니다. 그 표준에서 LF 와 CR 의 동작은 장치의 모드 설정에 따라 갈립니다. 제어 문자가 섞인 데이터를 앞에서부터 차례로 처리하지 않거나 고정 길이 레코드로 다루면 원하지 않은 효과가 날 수 있습니다. 원하는 동작이 나오게 하려면 따로 손을 봐야 할 수도 있습니다.
NUL 과 DEL 은 데이터 흐름에 넣거나 빼도 정보 내용이 바뀌지 않는 글자로 정해져 있습니다. 다만 정보가 놓인 모양이나 장치 제어에는 영향을 줄 수 있습니다.
예시
실물 ASCII 바이트열 두 벌입니다. 하나는 웹 요청 첫 줄의 바이트이고, 다른 하나는 파이썬이 ASCII 밖 글자를 ASCII 로 적으려다 실패하는 호출입니다.
HTTP 요청 첫 줄의 바이트
HTTP(HyperText Transfer Protocol)/1.1 요청은 첫 줄에 메서드, 공백, 요청 대상, 공백, 프로토콜 버전을 차례로 적습니다. 줄 끝은 CR LF 입니다. 아래는 GET /where?q=now HTTP/1.1 한 줄을 바이트로 풀어 쓴 것입니다. 윗줄이 글자, 아랫줄이 그 글자의 바이트입니다.
G E T SP / w h e r e ? q = n o w
47 45 54 20 2F 77 68 65 72 65 3F 71 3D 6E 6F 77
SP H T T P / 1 . 1 CR LF
20 48 54 54 50 2F 31 2E 31 0D 0A
27 바이트가 모두 7F 이하라 맨 앞 비트가 0 입니다. 첫 바이트 47 은 열 4, 행 7 이라 표에서 G 입니다. 공백은 20, 마지막 두 바이트 0D 0A 가 줄 끝 CR 과 LF 입니다.
받는 쪽은 0D 0A 를 보고 첫 줄이 끝난 줄 압니다. CR 없이 LF 하나만 와도 줄 끝으로 받아 줄 수 있습니다.
파이썬 ord() 와 encode('ascii')
파이썬의 ord() 는 글자를 번호로, chr() 는 번호를 글자로 바꿉니다. ord('a') 는 정수 97 을, chr(97) 은 문자열 'a' 를 돌려줍니다. 97 은 표의 6/1, 곧 바이트 61 입니다.
번호가 127 을 넘는 글자를 ASCII 로 적으려 하면 에러가 납니다.
>>> u = chr(40960) + 'abcd' + chr(1972)
>>> u.encode('utf-8')
b'\xea\x80\x80abcd\xde\xb4'
>>> u.encode('ascii')
Traceback (most recent call last):
...
UnicodeEncodeError: 'ascii' codec can't encode character 'ꀀ' in
position 0: ordinal not in range(128)
>>> u.encode('ascii', 'ignore')
b'abcd'
>>> u.encode('ascii', 'replace')
b'?abcd?'
chr(40960) 과 chr(1972) 는 번호가 127 을 넘는 글자입니다. 에러 메시지의 range(128) 이 ASCII 표의 0~127 입니다. 'ignore' 를 주면 그 글자를 버리고, 'replace' 를 주면 ?(3F)로 바꿉니다. 어느 쪽이든 원래 글자는 사라집니다.
UTF-8(Unicode Transformation Format 8-bit)로 적으면 같은 문자열이 바이트 여러 개가 됩니다. 그 가운데 abcd 네 글자는 ASCII 와 같은 바이트 61 62 63 64 로 남습니다.
갈래
ASCII 표를 바탕으로 무엇을 바꾸거나 더했느냐가 아래 셋을 가르는 축입니다. 판은 표 자체를 고쳐 온 것입니다. ISO 646 국가 변형은 같은 128칸 안에서 몇 칸을 바꾼 것입니다. 8비트 확장은 맨 앞 비트까지 써서 위쪽 128칸을 더한 것입니다.
판
ASCII 의 원전은 미국 표준 X3.4 이고 판이 여럿입니다. 「ASCII」라고만 부르면 보통 가장 최근 판을 뜻합니다. 앞선 판을 콕 집을 때는 「ASCII 63」처럼 발행 연도의 끝 두 숫자를 붙입니다. 인터넷 쪽이 네트워크 교환용으로 옮겨 온 판은 X3.4 의 1968년 판입니다.
이 판을 가리키는 이름은 문서마다 두 꼴로 적힙니다. USAS X3.4-1968 과 ANSI_X3.4-1968 입니다. 표준 번호 X3.4 와 연도 1968 은 같고 앞에 붙은 기관 이름만 다릅니다.
인터넷의 문자 집합 이름은 IANA(Internet Assigned Numbers Authority) 레지스트리가 관리합니다. 이 레지스트리는 ANSI_X3.4-1968 을 흔히 US-ASCII 또는 그냥 ASCII 라 부른다고 적습니다. 곧 ASCII 와 US-ASCII 는 같은 것입니다. 인터넷에서 쓰라고 권하는 이름은 US-ASCII 입니다. 등록된 출처는 미국 국가 표준 협회 ANSI(American National Standards Institute)의 ANSI X3.4-1986 입니다. ANSI_X3.4-1968 은 별칭으로 올라 있습니다.
국제 쪽에서는 ISO 646 이 1972년에 나왔습니다. 3판은 1991년에 나왔습니다. 1991년 판은 기준 변형 IRV 의 24 칸을 통화 기호 ¤ 에서 $ 로 바꿨습니다. 나머지 보이는 글자는 그대로 두었습니다. IANA 는 이 판의 ISO_646.irv:1991 도 US-ASCII 의 별칭으로 둡니다.
ISO 646 국가 변형
나라마다 표준 기관이 열린 12칸을 골라 자기 변형을 정합니다. 같은 나라 안에서도 한 칸만 다른 변형이 둘이면 이름을 따로 붙여 갈라야 합니다. 나라에 따로 필요한 글자가 없으면 IRV 의 글자를 같은 칸에 고르라고 강하게 권합니다.
| 변형 | IANA 이름 | 23 칸 |
5C 칸 |
|---|---|---|---|
| 미국 | US-ASCII |
# |
\ |
| 한국 | KSC5636 · ISO646-KR |
# |
₩ |
| 일본 | JIS_C6220-1969-ro · ISO646-JP |
# |
¥ |
| 영국 | BS_4730 · ISO646-GB |
£ |
\ |
일본 변형은 7E 칸도 물결표 ~ 대신 윗줄 ‾ 로 바꿉니다. 이 표만 봐도 앞 절의 표현 한계가 보입니다. 바이트 5C 를 어느 변형으로 읽느냐에 따라 글자가 셋으로 갈립니다.
8비트 확장
맨 앞 비트까지 쓰면 바이트 하나가 256칸이 됩니다. 8비트 부호 구조 표준 ISO 4873 은 7비트 표에서 나와 그것과 호환되는 8비트 부호를 정합니다. 아래쪽 128칸은 7비트 표와 같은 구조로 두고, 위쪽 128칸에 제어 문자 묶음과 보이는 글자 묶음을 하나씩 더합니다.
묶음에는 이름이 붙습니다. 제어 문자 묶음이 C, 보이는 글자 묶음이 G 입니다. 뒤에 붙는 숫자는 0 이 아래쪽 128칸, 1 이 위쪽 128칸입니다. 그래서 아래쪽에 C0 과 G0, 위쪽에 C1 과 G1 이 옵니다.
| 바이트 | 묶음 | 담는 것 |
|---|---|---|
00 ~ 1F |
C0 |
제어 문자 |
20 |
공백 SP |
|
21 ~ 7E |
G0 |
보이는 글자 94개. ISO 646 IRV 의 보이는 글자와 같습니다 |
7F |
DEL |
|
80 ~ 9F |
C1 |
제어 문자 32개까지 |
A0 ~ FF |
G1 |
보이는 글자 94개 또는 96개 |
위쪽 G1 을 무엇으로 채우느냐에 따라 표가 갈립니다. ISO 8859-1 부터 8859-4 까지는 라틴 알파벳 1~4번입니다. ISO 8859-5 는 라틴/키릴, ISO 8859-7 은 라틴/그리스입니다. 셋 다 글자 하나를 바이트 하나로 적습니다.
이런 8비트 표를 흔히 「확장 ASCII」라고 부릅니다. 그러나 ASCII 가 짝을 정한 것은 아래쪽 128칸뿐이고 위쪽 128칸은 표마다 다릅니다. 웹에서 「ascii」·「latin1」이라는 이름이 windows-1252 를 가리키게 된 것도 오랫동안 개발자를 헷갈리게 해 왔습니다.
사용처
오늘 ASCII 가 들어가 있는 표준과 규약입니다. 이름마다 ASCII 의 어느 부분을 쓰는지와 왜 그걸 골랐는지를 붙입니다.
UTF-8 과 유니코드
유니코드는 세상의 글자에 번호를 매기는 표준입니다. 그 번호를 코드 포인트라고 부릅니다. 첫 256개 코드 포인트는 ISO 8859-1 의 배치를 따르고, 그 가운데 첫 128개가 7비트 ASCII 입니다. 유니코드 코드 차트에서 U+0000~U+007F 구간의 이름은 「C0 Controls and Basic Latin」입니다.
flowchart TD
subgraph 유니코드["유니코드 코드 포인트"]
subgraph 첫256["첫 256개 · ISO 8859-1 의 배치"]
첫128["첫 128개 · 7비트 ASCII · U+0000~U+007F"]
end
end
UTF-8 은 U+0000~U+007F 를 바이트 00~7F 하나로 적습니다. 그 값의 바이트는 다른 글자 안에 나타나지 않습니다. 그래서 ASCII 문자열은 손대지 않아도 올바른 UTF-8 문자열입니다.
이 성질 덕분에 UTF-8 은 ASCII 값으로 구문을 가르는 소프트웨어와 맞물립니다. 파일 시스템이나 C 라이브러리의 printf() 처럼, ASCII 값만 보고 다른 값은 그냥 지나보내는 프로그램이 UTF-8 에서도 돕니다.
HTTP
HTTP 받는 쪽은 메시지를 US-ASCII 를 포함하는 인코딩의 바이트열로 파싱해야 합니다. 유니코드 문자열로 곧장 읽으면 보안 구멍이 생기기 때문입니다. 바이트 0A(LF)를 품은 잘못된 멀티바이트 열을 문자열 라이브러리마다 다르게 다룹니다.
메서드 이름과 필드 이름은 토큰입니다. 토큰은 공백과 구분자를 뺀 ASCII 보이는 글자로만 이뤄집니다. 필드 값은 보통 US-ASCII 범위로 제한됩니다. 새로 정의하는 필드는 값을 보이는 US-ASCII 글자와 공백 SP · 수평 탭 HTAB 로 제한하라고 권합니다.
필드 값에 CR · LF · NUL 이 들어 있으면 위험합니다. 구현마다 이 글자들을 다르게 파싱하고 해석하기 때문입니다. 받는 쪽은 그 메시지를 거부하거나, 그 글자를 SP 로 바꾼 뒤에 처리해야 합니다.
URI
URI(Uniform Resource Identifier) 문법은 US-ASCII 의 코드 값 위에 정의됩니다. URI 는 숫자, 글자, 몇몇 기호로 된 제한된 글자 집합으로만 이뤄집니다. 허용 집합 밖의 글자나 구분자로 쓰이는 글자를 담을 때는 퍼센트 인코딩으로 바이트를 적습니다.
JSON
JSON(JavaScript Object Notation) 문법의 구조 문자 여섯은 ASCII 바이트 값으로 정의됩니다. [ 는 5B, { 는 7B, ] 는 5D, } 는 7D, : 는 3A, , 는 2C 입니다.
메일과 Base64
SMTP(Simple Mail Transfer Protocol)의 명령과 응답은 ASCII 글자로 이뤄집니다. 확장을 쓰지 않은 SMTP 는 7비트 전송만 합니다. 일곱 비트 글자는 맨 앞 비트를 0 으로 비운 바이트에 담습니다. 서버와 확장을 협상하지 않은 클라이언트는 맨 앞 비트에 정보를 실어 보내면 안 됩니다. 그런 메시지를 받은 서버는 맨 앞 비트를 지우거나 메시지를 거부할 수 있습니다.
줄 끝은 CR LF 하나뿐입니다. 다른 글자나 글자 열을 줄 끝으로 알아보거나 만들어서는 안 됩니다. 한쪽만 홀로 나오는 CR 이나 LF 는 메일 구현에서 오랫동안 문제를 일으켜 왔습니다.
8비트 글자나 이진 데이터는 이 통로를 그냥 못 지나갑니다. 메일 첨부 규약 MIME(Multipurpose Internet Mail Extensions)은 데이터를 7비트 짧은 줄로 바꾸는 전송 인코딩을 둡니다. 7비트 데이터에는 127 을 넘는 바이트와 NUL 이 올 수 없습니다. CR 과 LF 는 CR LF 줄 끝으로만 나옵니다.
Base64 는 그 전송 인코딩 가운데 하나입니다. US-ASCII 의 65글자 부분집합을 써서 글자 하나에 6비트를 싣습니다. 이 부분집합을 고른 까닭은 ISO 646 의 모든 변형에서 같은 값으로 적힌다는 성질입니다. 국가 변형이 바꿀 수 있는 12칸은 이 부분집합에 들지 않습니다.
도메인 이름과 퓨니코드
퓨니코드(Punycode)는 국제화 도메인 이름을 위해 유니코드 문자열을 ASCII 문자열로 바꾸고 되돌립니다. ASCII 글자는 손대지 않고, ASCII 밖 글자는 호스트 이름에 허용된 ASCII 글자로 적습니다. 허용된 글자는 영문자, 숫자, 하이픈입니다.
관련 항목
ASCII 가 속하는 상위 분류
ASCII 를 정의하는 표준·문서
RFC 20 · ISO 646 · ECMA-6 · ANSI X3.4 · IANA 문자 집합 레지스트리
ASCII 표를 바탕으로 칸을 바꾸거나 더한 인코딩
ISO 8859 · ISO-8859-1 · windows-1252 · CP949 · EUC-KR · Shift_JIS · ISO-2022-KR
ASCII 의 128칸을 첫머리에 둔 유니코드 인코딩
유니코드 · UTF-8 · UTF-16 · 코드 포인트
ASCII 표 안에 들어 있는 문자 종류
제어 문자 · 개행 문자 · 널 문자 · 공백 문자 · 문장 부호 · CRLF
ASCII 제어 문자의 동작과 코드 확장을 정하는 표준
ECMA-48 · ISO 2022 · ECMA-43 · 이스케이프 시퀀스 · 코드 확장
ASCII 글자만 지나가는 통로에서 쓰는 전송 방식
Base64 · quoted-printable · MIME · 퍼센트 인코딩 · 7bit · 퓨니코드
ASCII 를 문법에 쓰는 프로토콜과 포맷
HTTP · URI · JSON · XML · SMTP · CSV
ASCII 를 바이트로 다룰 때 쓰는 단위와 표기
ASCII 표에 없는 글자를 적을 때 쓰는 장치와 나는 오류
다른 이름: ascii · 아스키 · American Standard Code for Information Interchange · 미국 정보 교환 표준 부호 · US-ASCII