---
title: "문자 인코딩 공부"
author: "Dne Cna"
published_at: "2026-09-28T12:18:29.100Z"
updated_at: "2026-09-28T12:18:29.100Z"
tags: ["문자 인코딩","인코딩","ascii","유니코드","utf-8","utf-16","utf-32","문자열 처리","base64","base62"]
canonical_url: "https://ariser.io/@writer_8706b598dfee/%EB%AC%B8%EC%9E%90-%EC%9D%B8%EC%BD%94%EB%94%A9-%EA%B3%A0%EC%9A%B0"
ai_assisted: false
---

# 문자 인코딩 공부

[원문](https://ariser.io/@writer_8706b598dfee/%EB%AC%B8%EC%9E%90-%EC%9D%B8%EC%BD%94%EB%94%A9-%EA%B3%A0%EC%9A%B0)

인터넷 세계의 문자는 아스키코드와 유니코드로 구성된다. 아스키코드는 8비트에 해당하는 1바이트로 간단한 기호, 숫자, 영어대소문자, 기능적 문자들을 나타냈다.

### 정확히 ASCII 코드란 무엇일까?

우리가 컴퓨터나 스마트폰에서 글을 읽고 쓸 때, 화면에 보이는 글자들은 사실 컴퓨터가 바로 이해할 수 있는 형태가 아닙니다. 컴퓨터가 기본적으로 이해하는 언어는 0과 1로 이루어진 숫자뿐이기 때문에, 글자나 기호 같은 '문자'도 결국 어떤 숫자로 바꾸어 저장해야 합니다. 이렇게 문자를 컴퓨터가 다룰 수 있는 숫자 코드로 바꾸는 것을 문자 인코딩이라고 부릅니다.

ASCII는 이런 문자 인코딩의 가장 대표적인 기본 규칙 중 하나입니다. ASCII는 American Standard Code for Information Interchange의 줄임말로, 직역하면 "정보 교환을 위한 미국 표준 코드" 정도가 됩니다. 말이 길어서 보통 그냥 "아스키 코드"라고 부릅니다.

그렇다면 ASCII는 실제로 어떻게 작동할까요? 아주 간단하게 말하면, ASCII는 우리가 자주 쓰는 글자와 기호들에 각각 숫자를 하나씩 정해 놓은 표입니다.

예를 들어 이런 식입니다.

    알파벳 대문자 A에는 65라는 숫자를 붙였다.
    알파벳 소문자 a에는 97이라는 숫자를 붙였다.
    숫자 0에는 48이라는 숫자를 붙였다.
    줄바꿈 기호, 물음표, 공백 같은 것에도 각각 정해진 숫자가 있다.

즉, 컴퓨터 입장에서는 "A"라는 글자가 따로 있는 것이 아니라, "65"라는 숫자를 저장하고, 그것을 화면에 표시할 때 "A"라고 보여 주는 것입니다. 우리가 키보드로 A를 누르면 컴퓨터는 A를 이해하는 것이 아니라, A에 해당하는 숫자 코드를 받아서 처리하는 셈이죠.

처음에는 ASCII 코드가 왜 필요했을까요? 컴퓨터끼리 서로 텍스트를 주고받으려면, 보내는 쪽과 받는 쪽이 "같은 글자는 같은 숫자로 표현하기로 약속"해야 합니다. 이런 약속이 없으면, 같은 글자라도 기기마다 전혀 다른 값으로 해석될 수 있습니다. ASCII는 그런 혼란을 줄이기 위해 만들어진 기본적인 표준이었습니다.

ASCII 코드의 중요한 특징 중 하나는 처음에는 영문 알파벳과 기본적인 기호 중심으로 만들어졌다는 점입니다. 그래서 영어권 환경에서 텍스트를 주고받는 데는 매우 편리했지만, 한글이나 일본어, 이모티콘처럼 다른 문자나 다양한 기호까지 표현하기에는 공간이 부족했습니다. 쉽게 말해, ASCII는 "가장 기본적이고 자주 쓰는 문자들부터 정리한 1차 표준"에 가깝다고 볼 수 있습니다.

또 하나 쉽게 이해할 수 있는 점은, ASCII가 생각보다 단순한 규칙에서 시작했다는 것입니다. 예를 들어 숫자 0부터 9까지의 코드는 순서대로 붙어 있고, 알파벳 대문자와 소문자도 서로 비슷한 위치에 배열되어 있습니다. 이런 규칙성 덕분에 사람들은 코드를 외우지 않아도, 대충 "어떤 범위에는 알파벳이 있구나", "이쪽은 숫자와 기호가 있구나" 하는 식으로 이해할 수 있습니다.

ASCII 코드를 이해하면 문자 인코딩 공부를 시작할 때 아주 좋은 출발점이 됩니다. 그 이유는 이후 등장하는 많은 인코딩 방식이 "ASCII가 다루는 기본 문자들을 그대로 포함하면서, 더 많은 문자를 표현할 수 있도록 확장한 것"이기 때문입니다. 즉, ASCII는 뒤로 나올 유니코드나 UTF-8 같은 개념을 공부할 때도 계속 reference가 되는 기본 중의 기본입니다.

정리하면, ASCII 코드는 글자와 기호를 숫자로 바꾸는 가장 기본적인 약속입니다. 컴퓨터가 문자를 어떻게 저장하는지 궁금할 때, 가장 먼저 떠올리기 좋은 예라고도 할 수 있습니다.


---

### ASCII만으로는 부족했다 — 유니코드의 등장

아스키 코드(ASCII)는 글자와 기호를 숫자로 바꾸는 아주 기본적인 약속이었습니다. 덕분에 영어 알파벳, 숫자, 간단한 기호 정도는 컴퓨터끼리 문제없이 주고받을 수 있었죠. 그런데 문제는 여기서 시작됩니다. 아스키코드는 영어 알파벳, 숫자, 간단한 기호만 표현할 수 있습니다.

그래서 나온 것이 **유니코드(Unicode)**입니다. 유니코드는 "전 세계의 문자들을 하나의 체계 안에서 표현하자"는 목표로 만들어진 문자 코드 체계입니다. 쉽게 말해, ASCII가 영어 중심의 작은 전화번호부였다면, 유니코드는 전 세계 모든 문자와 기호에 각자 고유한 번호를 붙여 주는 거대한 목록입니다.

여기서 중요한 점이 하나 있습니다. 유니코드는 "어떤 문자에 어떤 번호를 줄 것인가"를 정한 문자 집합에 가깝고, 그 번호를 실제로 컴퓨터에서 어떻게 저장하고 전달할지는 또 다른 문제입니다. 그 '저장 방식'과 관련된 것이 바로 UTF-8, UTF-16, UTF-32입니다.
유니코드 코드 포인트와 인코딩의 차이

처음 공부할 때 헷갈리기 쉬운 부분이 바로 이 지점입니다.

    코드 포인트(code point): 각 문자에 부여된 고유 번호입니다. 예를 들어 "A"는 U+0041, "가"는 U+AC00처럼 표현합니다. 여기서 U+는 유니코드 번호를 뜻하고, 뒤의 16진수가 코드 포인트입니다.
    인코딩(encoding): 그 코드 포인트를 실제로 바이트 단위로 어떻게 표현할지를 정한 규칙입니다.

즉, 같은 "가"라도 유니코드 세계에서는 정해진 코드 포인트가 있고, 이것을 UTF-8로 저장할지 UTF-16으로 저장할지 UTF-32로 저장할지에 따라 실제 바이트 배열이 달라집니다. 유니코드가 큰 지도라면, UTF 계열은 그 지도를 어떤 포장 방식으로 들고 다닐지 정하는 셈입니다.
UTF-8: 가장 널리 쓰이는 유연한 인코딩

UTF-8은 현재 인터넷에서 가장 흔하게 쓰이는 유니코드 인코딩입니다. 가장 큰 특징은 가변 길이라는 점입니다. 즉, 문자에 따라 사용하는 바이트 수가 달라집니다.

대략적인 특징은 이렇습니다.

    ASCII 범위의 문자, 예를 들면 영어 알파벳이나 숫자, 기본 기호는 1바이트로 표현됩니다. 이 덕분에 UTF-8은 기존 ASCII와 매우 호환성이 좋습니다.
    유럽 언어처럼 조금 더 다양한 문자는 보통 2바이트 정도로 표현되기도 합니다.
    한글, 한자, 이모티콘처럼 코드 포인트가 큰 문자들은 3바이트 이상이 될 수 있습니다.

UTF-8이 사랑받는 이유는 여러 가지입니다.

    영문 텍스트만 보면 저장 공간이 효율적입니다. ASCII와 거의 같은 크기처럼 느껴질 수 있습니다.
    다양한 문자와 언어를 한 번에 다룰 수 있습니다.
    웹, 파일, 통신 등 여러 환경에서 널리 쓰입니다.

다만 단점도 있습니다. 문자마다 길이가 다를 수 있어서, 예를 들어 "몇 번째 문자가 어디쯤에 있는지" 같은 계산을 할 때는 단순히 바이트 수만 보고 바로 판단하기 어려울 수 있습니다. CPU가 처리 방식에 따라 부하가 생길 수 있다는 이야기도 여기서 나옵니다.

하지만 일상적인 사용과 웹 환경에서는 장점이 훨씬 크기 때문에, UTF-8은 사실상 표준처럼 자리 잡았습니다.
UTF-16: 길이와 효율 사이의 타협

UTF-16도 유니코드를 표현하는 대표적인 방식입니다. 기본적으로는 2바이트 단위를 기준으로 생각하지만, 실제로는 가변 길이 인코딩입니다.

핵심은 이런 흐름입니다.

    많은 기본 문자는 2바이트로 표현됩니다.
    하지만 코드 포인트가 큰 일부 문자(예: 특정 이모티콘이나 보조 대입 문자 등)는 4바이트로 표현될 수 있습니다. 이때 짝이 되는 2바이트 단위 두 개를 함께 사용하는 방식을 떠올리면 이해하기 쉽습니다.

UTF-16은 ASCII 중심 환경에서는 UTF-8만큼 저장 효율이 항상 좋은 것은 아니지만, 특정 환경이나 기존 시스템에서는 의미가 있습니다. 예를 들어 내부 처리나 일부 운영체제, 일부 언어 환경에서 UTF-16을 기준으로 다루는 경우가 있습니다.

쉽게 말하면, UTF-16은 "대부분 문자는 2바이트로, 필요하면 4바이트까지" 확장하는 방식이라고 볼 수 있습니다. 다만 바이트 순서 같은 문제도 함께 생각해야 해서, 실제 데이터에서는 바이트 순서를 표시하기 위한 BOM(Byte Order Mark) 같은 개념이 따라오기도 합니다. 처음 공부할 때는 "UTF-16은 2바이트를 기본으로 쓰되, 더 큰 문자는 추가 바이트를 쓰는 가변 길이 방식" 정도로 잡아두면 충분합니다.
UTF-32: 가장 단순하지만 가장 무거운 방식

UTF-32는 세 방식 중에서 가장 직관적인 인코딩입니다. 거의 대부분의 유니코드 코드 포인트를 고정된 4바이트로 표현합니다.

장점은 단순함입니다.

    코드 포인트와 실제 저장 크기가 거의 1:1로 대응됩니다.
    문자 하나만 보면 길이를 예측할 수 있어 개념이 이해하기 쉽습니다.

하지만 단점도 분명합니다.

    작은 문자, 예를 들어 ASCII 범위의 글자 하나를 저장해도 4바이트가 필요합니다.
    텍스트가 길어지면 다른 인코딩보다 저장 공간이나 전송 데이터 크기가 커질 수 있습니다.

그래서 UTF-32는 실생활 텍스트 저장이나 웹 전송에서 널리 쓰이는 주된 방식은 아닙니다. 대신 내부 처리나 특정 프로그램에서 "문자 하나를 일정하게 다루고 싶을 때"처럼 단순함이 필요한 맥락에서 의미가 있습니다.

쉽게 비유하면, UTF-32는 "모든 문자에 똑같은 크기의 상자를 주는 방식"입니다. 다루기 쉬운 대신, 작은 물건에도 큰 상자가 필요해서 공간 효율이 떨어질 수 있습니다.
UTF-8, UTF-16, UTF-32를 한눈에 비교하기

처음 공부할 때는 아래처럼 정리해 두면 이해가 쉽습니다.

    UTF-8: 가변 길이. 영어 중심의 텍스트는 비교적 작고, 다양한 문자도 잘 표현합니다. 현재 가장 널리 쓰입니다.
    UTF-16: 기본 2바이트 중심의 가변 길이. 많은 문자를 2바이트로 다루지만, 큰 문자는 4바이트가 될 수 있습니다. 환경에 따라 쓰입니다.
    UTF-32: 거의 고정 4바이트. 단순하고 예측 가능하지만, 저장 효율이 떨어질 수 있습니다.

어떤 방식이 "가장 좋다"라기보다, 무엇을 중시하느냐에 따라 선택이 달라집니다.

    저장 공간과 웹 호환성을 중시하면 UTF-8이 유리합니다.
    내부 처리나 특정 플랫폼의 관행을 따라야 하면 UTF-16이 자연스러울 수 있습니다.
    개념을 단순하게 잡고 싶거나, 고정된 크기로 다루기 쉬워야 하는 맥락에서는 UTF-32가 이해하기 쉽습니다.

처음에는 이렇게 기억하면 충분하다

유니코드와 UTF 계열을 처음 접할 때 가장 중요한 것은 두 가지를 분리해서 보는 일입니다.

    어떤 문자에 어떤 번호를 줄 것인가 — 이것이 유니코드의 코드 포인트입니다.
    그 번호를 실제로 어떻게 바이트로 저장할 것인가 — 이것이 UTF-8, UTF-16, UTF-32 같은 인코딩입니다.

ASCII는 기본 문자들을 숫자로 표현하는 출발점이었고, 유니코드는 그 범위를 전 세계 문자로 넓힌 큰 틀입니다. 그리고 UTF 계열은 그 큰 틀의 번호를 실제 데이터와 저장, 전송에 맞게 포장하는 방식이라고 보면 됩니다.

처음에는 모든 세부 규칙을 외울 필요는 없습니다. "ASCII로는 부족해서 더 큰 문자 체계가 필요했고, 그 체계에서 코드 포인트를 정한 뒤, 실제로는 UTF-8이나 UTF-16 같은 방식으로 저장한다" 정도만 이해해도 인코딩 공부의 첫 관문은 충분히 넘은 셈입니다.

---

### 엔디안과 BOM - 코드 유닛을 바이트로 

> 1234를 표현할 때 12 34로 표현하는 방법을 '빅 엔디안' 이라고 하고 34 12로 표현하는 방법을 '리틀 엔디안'이라고 한다. 이건 외우라고밖에 말 못하겠다.

BOM은 Byte Order Mark의 약자로 파일의 맨 앞에 U+FEFF를 넣어(32비트) 이 글이 리틀앤디안인지/빅엔디안인지/ UTF-16인지 UTF-8인지 UTF-32 인지를 표시한다. UTF-8의 경우 시작 BOM 바이트가 'EF BB BF' 이다

### 한글 인코딩의 low level

한글을 어떻게 컴퓨터공학, 소프트웨어 분야에서 다루는지는 운영체제마다 다 다르다. 보통 애플의 전자기기를 활용하는 사람은 이유없이 한글이 고장나는 그런 현상 주기적으로 겪었을 것이다. 여러 가지 방법이 혼재되어 인터넷에서 사용되기 때문에 충돌이 존재하며 만약 컴퓨터공학을 좀 깊게 공부하고 싶은 사람은 여기서 어떻게 갈리는지를 좀 생각해보면 괜찮을 것 같다.

먼저 한글을 표현하는 대표적인 방법은 글자 하나하나를 전부 하나의 바이트표시로 넣는 '완성형'이 있다. 기본 발상은 ‘가’, ‘각’, ‘간’, ‘한’처럼 완성된 음절에 각각 코드를 배정하는 것이다. ‘한’을 저장할 때 초성 ㅎ, 중성 ㅏ, 종성 ㄴ을 따로 기록하는 대신, 문자표에서 ‘한’에 해당하는 값을 찾는다. 전통적인 KS X 1001 문자표에는 한글 완성 음절 2,350개가 직접 배정되어 있었다. 이 숫자는 모든 가능한 현대 한글 음절의 개수보다 작다. 따라서 그 표에 직접 들어 있지 않은 음절까지 처리하려면 추가 방식이 필요하다. 윈도우는 직접 모든 한글글자 가능한 조합 11172개를 전부 완성형으로 넣었다. 

그리고 '조합형'이 있다. 한글 음절을 구분비트 1개+초성5비트+중성5비트+종성5비트로 두면 16비트 하나만큼을 점유했을 때 모든 한글 글자를 초성과 중성 그리고 종성의 조합으로써 표현 가능하다. 
[참고:CPython 프로젝트의 한글 조합 인코더](https://github.com/python/cpython/blob/main/Modules/cjkcodecs/_codecs_kr.c)

유니코드에 표준이 정해지기 전엔 여러가지 방법들이 그때그때 편의에 맞게 난잡하게 쓰이다가, 유니코드에서 표준화된 한글 표현법은 완성형의 한글과 조합형의 한글이 각각 다른 표현으로써 존재하는 것이다. 
예를 들어 '한'이라는 단어는 완성형으로써 U+D55C도 '한'이라는 단어를 가리키고 조합형으로 U+1112 U+1161 U+11AB 형태로도 '한'이라는 단어를 가리킨다. 이 때 'ㄱ', 'ㅡ' 처럼 하나의 초성/중성만 쓰는 전용 호환 자모가 같이 별도로 존재한다는 점을 명확히 해야한다. 한글 관련해서 복잡한 처리를 지원하는 오픈소스들이 일반 사람들이 모르는 사이사이에 엄청나게 빡빡하게 예외케이스들 다 처리하도록 설계되어있음에 감사하자. 

또한 한 단어의 조합형 표현과 완성형 표현을 왔다갔다 하면서 분해/합성하는 NFD(정규 분해), NFC(정규 합성) 라이브러리도 표준으로써 자리잡아 있다

---

### 윈도우 환경에서 실제 적용

Windows에서 말하는 ANSI 코드페이지는 하나로 고정된 국제 공통 인코딩이 아니다. 나라마다 언어들을 표현하기 위한 각기 다른 인코딩들이 있다. 한글 페이지엔 '949', 일본어에는 '932' 등 여러가지 인코딩 방법으로써 혼재한다. 'GetACP() 함수를 통해서 어떤 인코딩을 하는지, 아니면 이걸 그냥 'CP_UTF8'형태로 표준에 해당하는 UTF로 강제하든지 디테일이 중요하다. 그리고 가끔 시스템코딩 등의 상황에선 UTF-16을 요하는 경우가 있는데 여기에선 API를 호출하는 지점에서 변환하는 것이 정말 중요하다. 평소엔 억지로 '어어 UTF-16 필요한데 써야지' 하지말자.


### base64인코딩이란 거도 있다.

RFC 4648이라는 국제표준으로 정해져있고 2진수로 010101010101110100 식으로 돼있는걸 6비트씩 끊어서 64비트짜리 표현으로 바꿔 압축하는 것을 말한다. ASCII만 봐도 텍스트가 아닌 문자들이 많고 이러한 텍스트가 아닌 문자들이 운영체제에 따라 해석에서 손실이 존재할 수 있어 텍스트로 채워진 64개의 표를 따라서 압축을 하여 외부로 전송할 때 쓰인다. 여기서 문제를 따로 일으킬 수 있는 '+' 와 '/' 를 빼 base62로 인코딩을 하기도 한다.


### 결론

AI시대일 수록 기본이 더 중요하고 기본을 더 깊게 알아야한다. 그래야 ai를 더 잘 쓰지






