문자열 인코딩

taypark·2020년 8월 31일
0

컴퓨터의 발명 이후 이기종간 데이터 교환을 위해 문자 인코딩의 표준을 맞추는 작업을 했다. 이를 위해 대표적으로 ASCII가 있었는데, 이는 영어 및 몇몇 특수문자 총 128개를 지원했다.

세계 국가들의 컴퓨터 사용으로 다른 언어의 문자 방식을 추가해야만 했고(예를 들어 한국어) 이를 위해 수십년이 걸렸다.

하지만 한글이 지원되는 문자 인코딩이 많다. 그러므로 문자 인코딩 방식을 맞춰주지 않으면 읽을 수 없는 문자가 있는 문제를 발생시킬 수 있다. 한글이 깨진다, 혹은 인코딩이 깨진다는 문제가 이런 문제인 것이다.

만약 웹 서비스를 배포하는 기업이 있다면, 데이터베이스, 웹 서버, 웹 소스, OS의 인코딩이 모두 동일한 방식으로 되어있는지 확인해야 한다.

만약 그렇지 않다면 인코딩으로 발생하는 데이터 뷰의 문제 또는 데이터타입을 생각하지 못하여 full index search 및 비교를 위한 데이터타입으로 추가 연산이 필요할 수 있다. 이는 CPU full load를 유발할 수도 있다. 이는 시스템의 장애로 작용하고, 데이터베이스 인덱스를 찾는 시간은 시간이 오래 걸리는 작업이다.

대표적인 인코딩 방식

ASCII, EUC-KR, CP949, UNICODE(대표적으로 utf-8) 가 있다. 하나씩 살펴보자.

  • 사전지식
    • 코드 포인트: 문자에 부여한 고유한 숫자 값. 예를들어 영문자 'A'는 0x41 같은 것이다.

1. ASCII(미국정보교환표준부호)

ASCII는 대표적인 문자 인코딩 방식이다. 대부분의 문자 인코딩이 ASCII에 기초를 둔다. 7 bit로 구성되어 있으며, 영어, 숫자, 특수문자, 기호, 제어문자 등 128개 문자를 표현할 수 있다. 또한 다른 확장된 인코딩 방식에서 ASCII와의 호환성이 존재한다.

미국에서 제정된 표준이기 때문에 영어 외의 다른 언어를 지원하지 않는다. 이의 필요성으로 8 bit의 확장 ASCII가 등장했고, 서유럽의 알파벳(알파벳에 특수문자가 더해진)과 몇몇 특수문자 128개를 추가적으로 지원했다. 이는 ISO-Latin-1 또는 ISO 8859-1로 불린다. Latin1은 확장형이므로 ASCII의 superset이다.

2. EUC-KR(Extended Unix Code-Korea, 확장 유닉스 코드-한국)

KS X1001과 KS X1003 표준안의 인코딩 방식이며, 한글 지원을 위해 유닉스 계열에서 나온 완성형 코드 인코딩이다. 즉, 완성된 코드 하나하나마다 코드를 부여한 것이다. 반대 되는 개념으로 조합형 코드 인코딩이 있다.

구분완성형 코드 인코딩조합형 코드 인코딩
누른 자판ㄱ + ㅏ + ㅁㄱ + ㅏ + ㅁ
실제 형식'감' 완성 인코딩ㄱ + ㅏ + ㅁ 각각 인코딩

문제는 만약 아무렇게나 친 같은 문자가 코드 테이블에 없다면, 이는 문자가 깨져보인다는 것이다.

EUC-KR의 문제점은 초기의 모든 한글을 포용하지는 않았다. 그래서 MS에서 이를 보완하여 문자셋을 만든다.

3. CP(코드페이지)

코드페이지는 특정한 문자 인코딩 테이블을 위해 쓰이는 전통적 IBM 용어이다. 문자 인코딩 테이블은 8 bit를 사용한다.

CP949는 한글을 지원하기 위해 윈도우즈 계열에서 나온 확장 완성형 코드 조합이다. MS에서 EUC-KR을 개선, 확장하여 만들었기때문에 MS949라는 이름으로도 불리며 EUC-KR를 호환할 수 있다. 확장형이기에 기본적으로 EUC-KR과 호환이 되며, EUC-KR에서 표현이 되지 않는 문자는 조합을 하여 표현한다. 참고로 일본어는 CP932, 중국어 간체는 CP936이다.

4. UNICODE

유니코드는 전 세계의 문자를 컴퓨터에서 일관되게 표현할 수 있도록 고안된 코드 조합이다. 즉, 현존하는 문자 인코딩 방법들을 모두 유니코드로 교체하려는것이 목적이다. 단, 유니코드가 코드 포인트를 매핑하는 방식은 아니다. 유니코드는 코드 조합 자체를 말한다. 그 방식은 아래에서 소개한다.

위의 자료는 W3에서 발표한 자료로, 2010년부터 2020년 2월까지 세계 문자 인코딩 비율을 나타낸다. 2010년 50%에서 가장 최근인 2020년 2월에 95%까지 육박했다.

유니코드는 2가지 매핑 방식이 있다.

  • 유니코드 변환(Universal Transformation Format, UTF)

  • 국제 문자 세트(Universal Coded Character, UCS)

UTF는 다음과 같은 형식이 있다.

  • UTF-1, 7, 8, EBCDIC, 16, 32 등이 있고

가장 많이 사용하는 방식은 UTF-8이다.

UTF-8(Universal coded character Set + Transformation Format - 8 bit)

유니코드를 위한 가변 길이 문자 인코딩 방식 중 하나이다. 유니코드 한 문자를 나타내기 위해 1~4 byte를 사용한다.

유니코드 코드 포인트를 나타내는 비트들은 여러 부분으로 나뉘어서, UTF-8로 표현된 바이트의 하위 비트에 들어간다. U+007F까지의 문자(128개)는 ASCII와 동일하게 표현된다.(이전 문자 포맷과 호환성을 위함) 이후 문자는 4 bytes 까지의 비트 패턴으로 표현할 수 있다.

자세한 것은 UTF-8 표를 가진 위키를 참조하자.

  • 장점
    • ASCII와의 하위호환성
    • XML 문서의 표준 인코딩
    • 다른 인코딩과의 왕복 변환이 가능하다.
    • 간단한 알고리즘이나 코드 삽입을 통해 UTF-8 문자열임을 확인할 수 있다.

결론

여러가지 문자 인코딩 방식에 대해 살펴봤다. 특히, 우리가 사용하는 한글을 중점으로 살펴봤다.

ASCII -> ISO-8859-1 -> EUC-KR -> CP949(MS949) -> UTF-8

순으로 발전해왔으며, 현재 가장 많이 사용하는 것은 UTF-8이다. 참고로 NGINX, MySQL, PHP, 웹브라우저 등에서도 기본으로 UTF-8을 사용하고 있다.

문자 인코딩은 단순히 문자를 코드 포인트로 바꾸는 작업이 아니라 데이터 통신시에 데이터를 정확하게 전송할 수 있는 기술 중 하나라는 것을 잊지 말아야한다.

문자열이 깨지면 일단 문자열 인코딩이 유니코드가 맞는지부터 확인하자.

참고자료

https://ko.wikipedia.org/wiki/UTF-8

https://ko.wikipedia.org/wiki/%EC%9C%A0%EB%8B%88%EC%BD%94%EB%93%9C

https://norux.me/31

profile
인생은 하드코어하게

0개의 댓글