본문 바로가기
Converter

아스키코드 변환기 (문자 ↔ ASCII 코드)

문자를 아스키코드로, 코드를 문자로 — 10·16·2·8진 동시에

각 글자를 코드로 바꿉니다. 한글·이모지는 ASCII가 아니라 코드포인트로 표시합니다

아스키코드표 (0~127)

회색은 제어문자
0NUL
1SOH
2STX
3ETX
4EOT
5ENQ
6ACK
7BEL
8BS
9HT
10LF
11VT
12FF
13CR
14SO
15SI
16DLE
17DC1
18DC2
19DC3
20DC4
21NAK
22SYN
23ETB
24CAN
25EM
26SUB
27ESC
28FS
29GS
30RS
31US
32SP
33!
34"
35#
36$
37%
38&
39'
40(
41)
42*
43+
44,
45-
46.
47/
480
491
502
513
524
535
546
557
568
579
58:
59;
60<
61=
62>
63?
64@
65A
66B
67C
68D
69E
70F
71G
72H
73I
74J
75K
76L
77M
78N
79O
80P
81Q
82R
83S
84T
85U
86V
87W
88X
89Y
90Z
91[
92\
93]
94^
95_
96`
97a
98b
99c
100d
101e
102f
103g
104h
105i
106j
107k
108l
109m
110n
111o
112p
113q
114r
115s
116t
117u
118v
119w
120x
121y
122z
123{
124|
125}
126~
127DEL

각 칸: 10진 코드 · 문자. 칸에 마우스를 올리면 16진값과 제어문자 이름이 보입니다. 0~31과 127은 화면에 안 찍히는 제어문자(NUL·TAB·LF 등), 32는 공백(SP)입니다.

아스키코드는 “글자에 번호를 매긴 표” 하나입니다

컴퓨터는 글자를 모릅니다. 0과 1, 곧 숫자만 압니다. 그래서 A를 저장하려면 먼저 글자마다 번호를 정해 두는 약속이 필요합니다. 그 약속 가운데 가장 오래되고 모든 것의 바탕이 된 것이 ASCII(American Standard Code for Information Interchange, 1963)입니다. A는 65번, a는 97번, 공백은 32번 — 이렇게 0부터 127까지 128개 글자에 번호를 매긴 표가 전부입니다. 위 변환기가 하는 일도 그 표를 양방향으로 찾아 주는 것뿐입니다.

왜 하필 127까지일까요. ASCII는 7비트 부호이기 때문입니다. 비트 일곱 개로 만들 수 있는 경우의 수가 27 = 128가지라, 0~127로 딱 떨어집니다. 그 시절 한 바이트(8비트)에서 남는 한 비트는 통신 오류를 잡는 검사용으로 썼습니다. 이 “2의 거듭제곱” 감각이 낯설다면 진법 변환기에서 왜 16진 한 자리가 4비트인지부터 보면 전체 그림이 맞춰집니다.

표에는 세 구역이 있습니다

128칸은 아무렇게나 채워진 게 아니라 세 덩어리로 나뉩니다.

  • 제어문자 (0~31, 그리고 127) — 화면에 안 찍히는명령입니다. 줄바꿈(LF·10), 탭(HT·9), 널(NUL·0), 백스페이스(BS·8), 벨(BEL·7) 등. 글자가 아니라 “동작”이라 변환기와 아래 표에서는 LF·TAB 같은 약어로 보여 줍니다.
  • 기호와 숫자 (32~64) — 공백(32), 문장부호, 그리고 숫자 0~9(48~57).
  • 글자 (65~122) — 대문자 A~Z(65~90), 소문자 a~z(97~122).

이 순서에는 뜻이 있습니다. 숫자가 글자보다 앞이고, 대문자가 소문자보다 앞입니다. 그래서 문자열을 코드값으로 그냥 정렬하면 Zebraapple보다 앞에 옵니다 — 대문자 Z(90)가 소문자 a(97)보다 작기 때문입니다. “사전순으로 정렬했는데 대문자만 위로 몰리는” 흔한 현상이 바로 이 아스키 순서의 결과입니다.

대소문자가 정확히 32 차이인 이유

표에서 가장 우아한 부분입니다. 같은 글자의 대문자와 소문자는 코드가 항상 정확히 32 차이 납니다.

A = 65 = 100 0001
a = 97 = 110 0001
              └ 이 한 비트(값 32 = 0x20)만 다르다

32는 2진수로 100000, 곧 비트 하나(0x20)입니다. A에 그 비트를 켜면 a가 되고, 끄면 다시 A가 됩니다. 대소문자 변환을 뺄셈도 조건문도 없이 비트 하나 토글로 처리하려고 설계자가 A~Z와 a~z를 일부러 그 간격에 놓은 것입니다. 위 변환기에서 Aa를 각각 넣어 2진 열을 비교하면, 정말 여섯 번째 자리 하나만 다른 것이 보입니다. 이건 케이스 변환기가 camelCase·snake_case를 다루는 것과는 다른 층위의 이야기입니다 — 저기는 표기법, 여기는 글자 한 개의 비트입니다.

숫자 문자 ‘5’는 숫자 5가 아니다

같은 원리가 숫자에도 있습니다. 문자 '5'의 코드는 53이지 5가 아닙니다. 숫자 문자 0~9가 48~57에 연속으로 놓여 있어서, 문자에서 48('0'의 코드)을 빼면 진짜 숫자가 됩니다 — 53 − 48 = 5. 사용자가 입력창에 친 "5"는 글자라 그대로 더하면 문자열이 이어 붙을 뿐("5" + "3" = "53") 계산이 안 됩니다. 텍스트로 들어온 숫자를 변환 없이 계산에 넣어 생기는 버그의 뿌리가 이 48 간격입니다.

줄바꿈은 왜 둘인가: CR과 LF

제어문자 중 실무에서 가장 자주 부딪히는 건 줄바꿈입니다. 그런데 줄바꿈 코드는 하나가 아니라 둘입니다.

CR (13, \r) — 커서를 줄 맨 앞으로 (Carriage Return)
LF (10, \n) — 종이를 한 줄 아래로 (Line Feed)

타자기에서 “다음 줄로”는 두 동작이었습니다 — 레버를 밀어 종이를 올리고(LF), 헤드를 왼쪽 끝으로 되돌리기(CR). 초기 컴퓨터가 이 관습을 그대로 물려받아, Windows는 줄 끝에 CR+LF 둘을, macOS·Linux는 LF 하나만 씁니다. 같은 텍스트 파일이 다른 OS에서 줄이 안 나뉘거나 줄 끝에 ^M이 붙어 보이는 문제가 정확히 여기서 옵니다. 참고로 여러 줄 텍스트의 CR/LF를 통일하고 눈에 안 보이는 제어·공백문자를 걷어내는 일은 이 zone이 아니라 형제 사이트 TextKit의 공백·줄바꿈 정리 도구가 맡습니다 — 이 변환기는 “한 글자 = 한 코드”를 보는 데 집중합니다.

“확장 아스키”라는 함정, 그리고 한글

여기서부터가 표만 보고는 알 수 없는, 그러나 문자 깨짐(���·?)의 원인 대부분을 설명하는 부분입니다. 순수 ASCII는 0~127, 128자가 전부입니다. 그런데 한 바이트는 0~255까지 담을 수 있으니, 남는 128~255 자리에 각자 글자를 얹기 시작했습니다. 문제는 그 표가 하나가 아니라는 것입니다.

  • ISO-8859-1(서유럽)에서 200번은 È
  • Windows-1252에서는 조금 다르고
  • CP949(옛 한글 인코딩)에서는 두 바이트를 묶어 한글 한 글자를 만듭니다

그래서 “확장 아스키”는 표준이 아니라 서로 안 맞는 여러 표의 모음입니다. 같은 200번이 어느 프로그램에서 열었느냐에 따라 다른 글자가 되고, 이것이 이메일·CSV·오래된 파일에서 글자가 깨지는 근본 원인입니다.

한글은 더 근본적으로 ASCII 밖입니다. 한글 음절은 11,172자라 256칸에 애초에 들어가지 않습니다. 그래서 한글은 ASCII가 아니라 유니코드를 씁니다 — 는 코드포인트 U+AC00(10진 44032)입니다. 이 변환기에 한글을 넣으면 코드는 계산해 보여 주되 “ASCII 아님”을 함께 표시합니다. 모르는 것을 아는 척 ?로 뭉개지 않기 위해서입니다. 이 유니코드 코드포인트를 HTML에 &#44032;처럼 넣거나 되돌리는 일은 HTML 엔티티 변환기가, 값을 16진·2진으로 펼쳐 보는 일은 진법 변환기가 이어받습니다.

정리

ASCII는 0~127의 글자에 번호를 매긴 7비트 표 하나입니다. 제어문자·숫자· 대문자·소문자가 이 순서로 놓였고, 그 배치 덕분에 대소문자는 비트 하나(32) 차이, 숫자 문자는 48만 빼면 값이 됩니다. 줄바꿈이 CR·LF 둘로 갈리는 것도, 128~255의 “확장 아스키”가 서로 안 맞는 것도, 한글이 여기 없는 것도 모두 이 128칸의 한계에서 나옵니다. 화면 위쪽 변환기로 코드를 확인하고, 아래 0~127 아스키코드표를 옆에 두면 표가 더는 외울 대상이 아니라 “구조가 보이는 지도”가 됩니다.

자주 묻는 질문

왜 대문자 A가 65인가요?
1963년 ASCII를 설계할 때 코드 배치를 '쓰기 편하게'가 아니라 '기계가 처리하기 편하게' 정했기 때문입니다. 0~31은 화면에 안 찍히는 제어문자, 32는 공백, 33~47은 기호, 48~57은 숫자 0~9, 65~90은 대문자 A~Z, 97~122는 소문자 a~z 순서입니다. 숫자 0이 48(16진 0x30), 대문자 A가 65(0x41), 소문자 a가 97(0x61)로 딱 떨어지는 자리에 놓인 건 우연이 아니라, 뒤에 설명하는 비트 연산 트릭을 쓰려고 일부러 그렇게 배치한 것입니다.
대문자와 소문자 코드가 왜 정확히 32 차이인가요?
대소문자 변환을 뺄셈이 아니라 비트 하나로 처리하려고 그렇게 맞췄습니다. 32는 2진수로 100000, 즉 여섯 번째 비트(0x20) 하나입니다. A(65, 1000001)에 이 비트를 켜면 a(97, 1100001)가 되고, 끄면 다시 A가 됩니다. 그래서 옛 코드가 소문자로 바꿀 때 'code | 0x20', 대문자로 바꿀 때 'code & ~0x20'을 쓰는 걸 볼 수 있습니다. 위 변환기에서 A와 a를 각각 2진으로 보면 딱 그 한 자리만 다른 것이 눈에 보입니다.
확장 아스키코드(128~255)는 뭔가요? 한글도 아스키코드가 있나요?
순수 ASCII는 0~127까지, 딱 128자뿐입니다. 128~255는 '확장 아스키'라고 부르지만 표준이 하나가 아닙니다 — Windows-1252, ISO-8859-1(라틴), CP949(한글) 등 나라·프로그램마다 다른 표를 그 자리에 얹었습니다. 그래서 같은 200번이 어디서는 é, 어디서는 다른 글자입니다. 한글은 그 256칸에 다 담을 수 없어(11,172자) 애초에 ASCII가 아니라 유니코드를 씁니다. 이 변환기에 한글을 넣으면 코드는 보여 주되 'ASCII 아님'을 함께 표시하는 이유입니다.
줄바꿈(엔터)의 아스키코드는 무엇인가요? CR과 LF는 왜 둘인가요?
줄바꿈은 하나가 아니라 둘입니다 — LF(10, \n)와 CR(13, \r). 타자기 시절 '커서를 줄 맨 앞으로(CR)' 와 '종이를 한 줄 올리기(LF)' 가 별개 동작이었던 데서 왔습니다. 그 유산으로 지금도 Windows는 줄 끝에 CR+LF 둘을, macOS·Linux는 LF 하나만 씁니다. 같은 파일이 한쪽에서 줄이 안 나뉘거나 줄 끝에 ^M이 보이는 문제가 여기서 생깁니다. 줄바꿈 문자 통일은 이 zone의 형제 도구인 텍스트 정리 도구가 다룹니다.
DEL(127)은 제어문자인데 왜 맨 끝에 있나요?
천공 카드(종이 테이프)의 흔적입니다. 다른 제어문자는 0~31에 모여 있는데 DEL만 127, 즉 2진수로 1111111(일곱 비트 전부 1)입니다. 종이 테이프에 이미 뚫은 구멍은 메울 수 없으니, 잘못 친 자리는 구멍 일곱 개를 전부 뚫어 '삭제(DEL)'로 표시했습니다. 그 값이 그대로 127에 남은 것입니다. 그래서 DEL은 제어문자면서도 코드표의 맨 끝에 홀로 있습니다.
숫자 '5'와 숫자 5는 왜 다른가요?
문자 '5'의 아스키코드는 53(16진 0x35)이고, 정수 5는 그냥 5입니다. 둘은 완전히 다른 값입니다. 그래서 문자로 받은 '5'를 숫자로 쓰려면 코드에서 48('0'의 코드)을 빼야 합니다 — 53 − 48 = 5. 숫자 문자 0~9가 48~57에 연속으로 놓인 덕분에 이 뺄셈 하나로 어떤 숫자 문자든 값으로 바뀝니다. 텍스트로 들어온 숫자를 계산에 바로 썼다가 틀리는 버그가 이 차이를 몰라서 납니다.