최근 수정 시각 : 2024-11-15 02:48:58

인코딩

디코딩에서 넘어옴

[[컴퓨터공학|컴퓨터 과학 & 공학
Computer Science & Engineering
]]
[ 펼치기 · 접기 ]
||<tablebgcolor=#fff,#1c1d1f><tablecolor=#373a3c,#ddd><colbgcolor=#0066DC><colcolor=white> 기반 학문 ||수학(해석학 · 이산수학 · 수리논리학 · 선형대수학 · 미적분학 · 미분방정식 · 대수학(환론 · 범주론) · 정수론) · 이론 컴퓨터 과학 · 암호학 · 전자공학 · 언어학(형태론 · 통사론 · 의미론 · 화용론 · 음운론) · 인지과학 ||
하드웨어 구성 SoC · CPU · GPU(그래픽 카드 · GPGPU) · ROM · RAM · SSD · HDD · 참조: 틀:컴퓨터 부품
기술 기계어 · 어셈블리어 · C/C++ · C# · Java · Python · BIOS · 절차적 프로그래밍 · 객체 지향 프로그래밍 · 해킹 · ROT13 · 일회용 비밀번호 · 사물인터넷 · 와이파이 · GPS · 임베디드 · 인공신경망 · OpenGL · EXIF · 마이크로아키텍처 · ACPI · UEFI · NERF · gRPC · 리버스 엔지니어링 · HCI · UI · UX · 대역폭 · DBMS · NoSQL · 해시(SHA · 브루트 포스 · 레인보우 테이블 · salt · 암호화폐) · RSA 암호화 · 하드웨어 가속
연구

기타
논리 회로(보수기 · 가산기 · 논리 연산 · 불 대수 · 플립플롭) · 정보이론 · 임베디드 시스템 · 운영 체제 · 데이터베이스 · 프로그래밍 언어{컴파일러(어셈블러 · JIT) · 인터프리터 · 유형 이론 · 파싱 · 링커 · 난해한 프로그래밍 언어} · 메타데이터 · 기계학습 · 빅데이터 · 폰노이만 구조 · 양자컴퓨터 · 행위자 모델 · 인코딩(유니코드 · MBCS) · 네트워크 · 컴퓨터 보안 · OCR · 슈퍼컴퓨터 · 튜링 머신 · FPGA · 딥러닝 · 컴퓨터 구조론 · 컴퓨터 비전 · 컴퓨터 그래픽스 · 인공지능 · 시간 복잡도(최적화) · 소프트웨어 개발 방법론 · 디자인 패턴 · 정보처리이론 · 재귀 이론 · 자연어 처리(기계 번역 · 음성인식) · 버전 (버전 관리 시스템 · Git · GitHub)

1. 영어 단어 encoding2. 문자 인코딩
2.1. 개요2.2. ASCII2.3. MBCS 춘추전국시대한글 인코딩2.4. 유니코드 발족 이후의 역사
2.4.1. UCS-22.4.2. UTF-162.4.3. UTF-8
2.5. 관련 문서
3. 문자열 인코딩
3.1. URL 관련3.2. 마크업 언어 관련3.3. 바이너리 관련
4. 멀티미디어(동영상, 소리) 인코딩

1. 영어 단어 encoding

코드화, 암호화를 의미한다. 한자어 표현으로 부호화(符號化)라고도 말한다. 반대말디코딩(decoding, 복호화).

어떤 정보를 정해진 규칙(Code[1])에 따라 변환하는 것(en-code-ing)을 일컫는다.

세계 대전 시절에는 모스 부호(Morse Code)가 대표적인 인코딩 행위였고, 20세기 후반부터는 디지털(0,1) 관련해서 인코딩이 이루어졌다. 속성상 단순 변환을 넘어 암호화, 압축의 의미로 아울러 사용되기도 한다.

일반인들 입장에서는 문자가 깨졌을 때, 음악파일이나 동영상파일을 재생할 수 없을 때 비로소 접하게 되는듯 하다. 참고로, 컴퓨터에서 인코딩은 동영상이나 문자 인코딩 뿐 아니라 사람이 인지할 수 있는 형태의 데이터를 약속된 규칙에 의해 컴퓨터가 사용하는 0과 1로 변환하는 과정을 통틀어 일컫는다. 이 경우 샘플링이라고도 하며, 디지털 문서에 잘 설명되어 있다. 관습적으로 압축을 하지 않은 RAW 데이터를 샘플링 데이터, 압축 등으로 인해 알고리즘을 모르면 읽을 수 없는 데이터를 인코딩된 데이터로 나눠 쓰는 듯 하나 꼭 그렇다는건 아니라는 것은 알아두자.

2. 문자 인코딩

2.1. 개요

문자 코드를 전산기기 안에서 0, 1로 저장하는 방식.

많은 사람들이 문자 코드와 문자 인코딩을 잘 구분하지 못하지만, 이 둘은 "부호화"라는 관점에서 같지만 "개념"은 엄연히 다르다. 1바이트 인코딩 시절에는 이 둘을 구분할 이유가 별로 없었지만, 다국어지원 및 유니코드 체계하에서 2바이트 이상의 인코딩이 필요해지고, 효율성과 호환성에 따라 다양한 인코딩 방법이 등장하면서 이 둘을 잘 구분해야 할 필요가 생겼다.

문자 코드는 문서를 전자화하기 위해, 각 문자와 추상적인 숫자 사이를 짝지어 놓은 것이다. 이와 반대로, 인코딩은 이 숫자를 실제의 전산기기 안에서 저장, 처리하기 위해 만들어진 숫자의 표현 형식이다. 예컨대,
  • 문자코드 : '가', '나', '다', '하' 문자를 각각 숫자 1, 2, 3, 14에 짝지어놓은 것.
  • 한 자릿수 인코딩 : 1, 2, 3이라 적혀 있으면 '가', '나', '다' 이고, '하'는 쓸 수 없다.
  • 두 자릿수 인코딩 : 01, 02, 03, 14라 적혀 있으면 '가', '나', '다', '하'이다.
  • 여덟 자릿수 인코딩 : 00000001, 00000002, 00000003, 00000014라 적혀 있으면 '가', '나', '다', '하'이다. 장점은 더 많은 문자코드를 수용할 수 있다는 것, 단점은 별 것 아닌 일에 쓸 데 없는 자릿수(=용량)을 차지한다는 것.
  • 엔디안이 다른 인코딩 : 10000000, 20000000, 30000000, 41000000라 적혀 있으면 '가', '나', '다', '하'이다. 앞에서부터 읽을 때 숫자를 전부 읽기 전에 중요한 숫자를 이미 읽어내어 빠르고 효율적인 처리를 할 수 있다.[2] 단점은 41을 14로 이해하지 못하고 41로 읽어버리면 엉뚱한 글자를 출력하게 된다는 것.
  • 가변 인코딩 : 1, 2, 3, 0, 1, 0, 4라 적혀있으면 '가', '나', '다', '하'이다. '하'를 쓰기 위해 0104로 네자릿수를 쓰게 되었지만, 한 자릿수 인코딩과 호환이 된다.
등등 이런 식으로 비유를 할 수 있다.

2.2. ASCII

초창기의 컴퓨터는 사람과 기계어로만 소통을 했었고, 당연히 사용 과정에 상당한 애로사항을 겪었다. 그래서 어셈블리어 등의 사람이 쓰는 문자를 사용할 필요성이 생겼기 때문에, 라틴 문자숫자, 몇몇 특수문자를 128개([math(2^7)])의 코드값에 1:1 대응시키는 법을 고안했고, 이것이 바로 최초의 문자 코드라고 할 수 있는 ASCII(American Standard Code for Information Interchange)다.

아스키는 [math(2^7)] 곧 7비트로 이루어졌고, 1바이트 단위로 통신할 때 나머지 1비트는 패리티 코드로 쓰게 되어 있었다. 아스키는 이름에서 나오듯이 근본적으로 정보 교환을 위한 규격이었고, 통신 에러를 감지하기 위한 체크섬이 필요했기 때문이었다. 그러나 이런 간단한 체크섬은 얼마든지 회피할 수 있는 에러들이 발생할 수 있었고, 그래서 이런 패리티 코드는 곧 쓰이지 않게 되었다. 컴퓨터가 8비트=1바이트를 사용하게 되자 대부분의 컴퓨터 업체들은 아스키코드의 7비트 맨 앞에 0비트를 써서 8비트를 채운 인코딩을 쓰게 되었다.

ASCII의 이름에서 볼 수 있듯 미국에서 만들어졌는데, 미국에서 쓰이는 영어를 쓰기 적합한 형태로 만들어졌다. 영어에서 쓰이는 라틴 문자는 diacritics가 없다시피 하기 때문에[3] 넣기가 쉬웠던 것.

하지만 당장 라틴 문자를 공유하는 유럽쪽 언어[4]와, 한자, 한글, 가나, 아랍어 따위의, 영어를 제외한 나머지 언어나 글자는 사용할 수 없었다. 그래서 8비트 아스키부호화에서 비어있는 127뒤의 빈 자리를 다양한 글자로 채워넣는 부호화들이 등장했는데, 표준이 아니었으므로 회사마다 모두 다른 글자를 할당했고, 또 각국이 자국어표기를 위해 이 공간을 활용하면서 표준화의 지옥문이 열렸다.

2.3. MBCS 춘추전국시대한글 인코딩

여덟번째 비트 자리를 활용하게 되면서 이른바 헬게이트가 열려버렸다. 국경을 벗어나면 코드가 깨져버린다는 것이다. 예컨대 미국에서 제작된 대부분의 SW에서 확장아스키 127 이후의 영역은 프로그램 테두리 등을 그리기 위한 선문자에 할당되었는데[5], 완성형 한글이 로드된 DOS에서 그 프로그램을 로드하면 이 테두리가 모두 깨진 한글로 표현되었다.
파일:external/www.dal.kr/a010101.gif
이렇게. 쳐컴컴컴컴컴컴컴컴캑[6]

영어 이외의 언어를 위해서는 국가별로 인코딩 표준을 만들어야 했고, 그 중 대표적인 것이 한국의 완성형조합형. 하지만 이것도 한계가 있었고, 한 문서에 여러 언어를 써야 하는 상황(외국어 학습용 교재 등)에서는 그야말로 답이 없었다.

그래서, 이 문제를 해결하기 위해 모든 문자 체계를 한데 몰아넣은 인코딩, 유니코드가 탄생하게 되었다.

2.4. 유니코드 발족 이후의 역사

2.4.1. UCS-2

2 Byte - Universal Character Set. 최초의 유니코드 인코딩인 "고정 2바이트 문자 인코딩".

1980년대부터 7비트 아스키코드의 한계를 벗어나면서 좀더 많은 문자를 표현할 수 있는 멀티바이트 인코딩에 대한 요구가 늘어나며 유니코드 위원회가 발족되었다. 최초의 유니코드 초안에 포함된 문자들은 2^16개(65536개)를 넘지 않았으므로 이진수 16자릿수=2바이트를 써서 인코딩을 하면 모든 문자를 쓸 수 있었다.

그러나 유니코드에 점점 더 많은 문자와 기호들이 추가되자 65536개를 넘어서서 2바이트 안에 다 담을 수 없는 사태가 발생했다.[7] 그래서 IEEE에서 고정 4바이트(32비트)를 사용하는 UCS-4 인코딩을 제안하였다. 그러나 유니코드 콘소시엄을 구성하는 대부분의 회사들은 이미 2바이트 기반 기술에 너무 많은 투자를 해놓은 상태였던 데다가, 대부분의 라틴문자가 8비트 안에 들어가고, 세상에서 주로 사용되는 문자 거의 대부분[8]이 2바이트 이내에 들어가는 상황에서 한 글자당 4바이트 인코딩은 지나친 용량의 낭비라는 점이 문제가 되어 거의 채택되지 않았다.

2.4.2. UTF-16

16-bit Unicode Transformation Format.

고정 길이의 한계를 해결하기 위해 가변 길이 인코딩 기법인 UTF-16이 등장하였는데, 이는 기본적으로는 UCS-2와 같지만, 2바이트를 넘어서는 문자에 대해서는 4바이트로 표현하는 것이다. 이를 위해 0xFFFF[9]를 넘는 값을 가지는 유니코드는 코드값에서 0x10000을 뺀 뒤 20비트로 표현하여 이것을 10비트씩 쪼개어, 각 10비트값에 각각 0xD800[10]과 0xDC00[11]을 더해서 2개의 16비트(총32비트)로 인코딩하는 것이다.

이렇게 하여 일반적인 상황(대부분의 한글, 한자, 일본어 등을 포함한 기본 다국어 평면)에서는 기존의 UCS-2 16비트 인코딩과 호환을 유지하면서도 16비트를 넘어서는 문자를 가변 길이 인코딩으로 표현가능하게 되었다.

UCS-2와 UTF-16 끼리는 호환되었으나, 이들은 기본 아스키 코드로 작성된 문서와는 호환되지 않았고, 설상가상으로 컴퓨터 시스템에 따라 1Word 내에서 byte의 순서를 처리하는 방식이 모두 달랐기 때문에 호환성에 문제가 있었다. 일명 엔디안 문제. 이 때문에 BOM(Byte Order Mark)를 달아서 빅/리틀 엔디안을 구분하게 되어 있지만 시스템에 따라 달지 않는 경우도 있는 등 혼파망.

오죽하면 인터넷에서의 정보교환에는 '유니코드'[12]나 'UTF-16'을 아예 쓰지 말라고 권고하는 글을 심심찮게 볼 수 있다. PHP에서 이걸 PHP6의 차세대 기본 인코딩으로 밀었다가 여론의 뭇매를 얻어맞아 프로젝트 자체가 좌초되고 PHP5에서 바로 PHP7로 건너뛰기도 했다.

2.4.3. UTF-8

8-bit Unicode Transformation Format.
UTF-8은 최소 1바이트, 최대 4바이트를 사용하는 가변 인코딩이다. 최초 7비트 이내의 영역에서는 ASCII와 완전히 호환되기 때문에 현재는 문자 전송의 사실상 표준이 되어 있다. 자세한 사항은 UTF-8 문서 참조.

2.5. 관련 문서

3. 문자열 인코딩

문자열을 별도의 방식으로 치환하는 인코딩. 엄밀히 말하면 상위의 문자 인코딩과는 다른 개념이며 문장의 코드화에 가깝다.

문자입력/전송시, 읽지 않는 문자나 기존 예약된 문자가 따로 있어 사용할 수 없는 문자가 있을 때, 이를 회피하기 위해서 돌려 인코딩을 하는 경우가 많다. 또한 표현하는 한도를 넘은 문자열을 집어넣고자 할 때 따로 약속된 코드로 인코딩을 하기도 한다. 심지어는 문자가 아닌 정보를 문자처럼 기록하고자 할 때 별도의 인코딩을 하기도 한다.

보통 URL이나, HTML같은 웹 관련 텍스트에서 종종 마주할 수 있다.

3.1. URL 관련

  • URL escape code (퍼센트 인코딩): URL에 공백(스페이스바)를 사용할 수 없는 등의 이유로 별도의 코드를 부여한 URL 기입 방식. 서버에 저장된 첨부파일명을 URL로 표현하기 위해 퍼센트인코딩이 된 파일명으로 바꾸기 때문에, 서버에서 다운로드 된 파일명에 %20, +, %5B 등의 텍스트가 붙어 나오는 경우로 많이 접한다.
  • 퓨니코드 (국제화 도메인 네임용): URL에 다국어문자(ASCII와 다른 유니코드 문자)를 표기하기 위해 만들어진 인코딩. http://xn\aaaaaa.xn\aaaaaaa 류의 주소가 이에 해당한다.

3.2. 마크업 언어 관련

마크업에 사용된 기 예약된 문자가 있기 때문에, 이를 회피하여 문자열을 작성해야 하는 이슈가 있다. 다만, 이 경우 인코딩이라기 보다는 "문법"에 더 가깝게 받아들여진다.

예를 하나 들자면 NBSP가 있는데, HTML에서 공백(스페이스바)를 읽지 않아 &nbsp; 등의 문자로 치환하여 작성해야 한다.

HTML, XML, 마크다운(=위키) 등의 문서를 작성할 때 신경써야 한다.

3.3. 바이너리 관련

  • BASE64: 바이너리(e.g. 이미지) 데이터를 문자 코드에 영향을 받지 않는 공통 ASCII 문자로 표현하기 위해 만들어진 인코딩. 쉽게 말해 이미지를 지원하지 않는 댓글창에 문자열로 이미지를 우겨넣기 위해 사용한다. (...라기 보다는 DB에 이미지 썸네일을 저장하기 위해 사용한다.)[14]
  • 아스키 아트 : 이미지를 문자로 표현하지만, BASE64와는 다르다(...)

4. 멀티미디어(동영상, 소리) 인코딩

4.1. 개요

동영상/소리를 저장하는 방식. 문자 인코딩이 부호화와 관련이 깊다면, 멀티미디어 인코딩은 압축알고리즘과 관련이 깊다. 주로 재생기기, 프로그램 등과 호환되는 코덱으로 변환, 동영상/소리의 용량을 줄이는 데에 필요하다.[15]

4.2. 코덱

코덱은 코더와 디코더의 줄임말로 동영상/소리 인코딩 알고리즘 종류를 지칭한다. 영상코덱으로 H.264, H.265, VP9, AV1, 음성코덱으로 MP3, AAC, Opus 등 여러 종류가 있다.

4.3. 동영상 인코더

이름대로 동영상을 인코딩 하는 프로그램. 동영상파일의 정체는 비디오스트림과 오디오스트림의 결합이므로, 이를 다루는 프로그램은 동영상 인코더라는 이름을 갖고 있지만 영상코덱과 음성코덱 모두를 다룰 수 있다.

인코딩은 일종의 압축과정이며 압축률이 높을수록 컴퓨터 자원을 많이 소모한다. 그 자원(CPU, GPU)을 효율적으로 사용하기 위해서 CUDA, OpenCL같은 기술을 사용하기도 한다. 어떤 인코더를 쓰느냐에 따라 인코딩 속도와 화질에 차이가 있다.

[1] 드레스 코드 등[2] 일례로, 119를 부를 때 000-0000-0911를 누르는 대신 119(이하생략)만 눌러도 된다.[3] résumé, naïve와 같이 diacritics가 있는 영어 단어가 있기는 하지만, 죄다 프랑스어 직수입 어휘이며 그나마도 이런 단어는 몇 없기 때문에 사실상 diacritics를 쓰지 않는 언어라고 봐도 무방하다. diacritics를 쓰지 않는 또다른 언어는 바로 라틴 문자라는 이름의 유래가 된 라틴어.[4] 이런 언어는 글자부호(다이어크리틱)를 많이 쓴다. 같은 문자에서 유래하면서도 글자 어딘가에 부호를 더하면, 같은 알파벳인 것 같으면서 글자부호가 다르면 아예 다른 뜻이거나 글자가 된다.[5] 당시는 GUI환경을 위한 기반이 제대로 갖춰지지 않아서 문자 기반 환경에 선문자를 출력해서 테두리나 표 등을 그렸다.[6] 한자로 된 부분은 袴(바지 고) 자이다. 일본어로는 하카마로 읽는 것으로 알려진 한자이다.[7] 유니코드 문서에서도 알 수 있지만 현재까지 할당된 문자들은 최대 4바이트까지 쓰이고 있다.[8] 기본 다국어 평면, BMP.[9] 이진수 1111 1111 1111 1111, 즉 16비트로 표현할 수 있는 최대 숫자.[10] 1101 10 00 0000 0000[11] 1101 11 00 0000 0000, 참고로 가변길이 인코딩에 사용되는 이 두 유니코드값은 유니코드표에서는 이 용도로 쓰기 위해 비워두었다.[12] 원래 UCS-2라고 써야 맞겠지만 이런 식으로 부정확하게 언급된다. 윈도우 기본 메모장에서 저장할 때 인코딩 선택 메뉴에서 UCS-2를 '유니코드'라고 써놨기 때문. 결국 Windows 10 1903에서 UTF-16으로 변경되었다.[13] 서로 다른 OS에서의 결합 문자를 다루는 방식, 모아쓰기풀어쓰기의 "정규화" 방식을 다룬 테이블. 맥에서 압축한 파일명이 윈도우에서 풀어쓰기 되는 현상의 원인이다.[14] 그런데 이 용도를 위한 BLOB 타입의 컬럼이 따로 있고 바이너리를 16진수로 변환하는 함수를 쓰면 되기 때문에 BASE64를 쓰기에는 효율이 떨어진다.[15] 단 소리는 충분히 적은 용량으로 압축이 되었다는 것이 세간의 인식이며(mp3, 화질을 높이고 용량을 줄이는 영상 인코딩 중심으로 코덱이 부지런히 발전하고 있는 중이다.