대표적인 인코딩 오류 사례

문서를 편집하면서 또는 일상생활에서 다음과 같은 인코딩 오류를 접하는 경우가 심심치않게 있습니다.

저런 외계어(?)는 어떤 경우에 볼 수 있을까요??
이번 글에서 인코딩과 디코딩 개념에 대해 알아보고 문자열(String)을 저장소에 저장할 때 사용하는 방법인 문자열인코딩에 대해 소개하겠습니다.



인코딩/디코딩이란?

먼저 컴퓨터에서 문자를 저장하는 방법에 대해 간단히 알아보겠습니다.
컴퓨터에서는 데이터를 이진수로 저장하는데 예를들면,

ABC -> 0x61, 0x62, 0x63

와 같이 변환해 저장하는데 이것을 '인코딩(부호화)'라고 합니다.
또한 저장소에 저장해둔 0x61을 해석해서 우리가 아는 형태의 문자로 되돌리는 것을 '디코딩(복호화)'라고 합니다.



charset(문자집합)

우리가 아는 문자들을 컴퓨터가 이해할 수 있는 형태로 변경하는 것이 인코딩이라고 했습니다.
그렇다면 문자와 이진수 사이에 변환하는 규칙이 있어야합니다. 가장 잘 알려진 변환 규칙이 바로 ASCII Table(아스키 코드표) 입니다.

영문자, 숫자, 일부 특수키와 기호 등 총 128가지의 문자를 이진수로 변환할 수 있는 맵핑 규칙을 나타낸 표입니다.
아스키 코드표와 같은 규칙을 charset(문자집합)이라고 합니다.

그런데 아스키 코드 128가지 문자 이외의 문자를 표현할 수 없는 단점을 가지고 있습니다. 이러한 단점을 보완하기 위해 국가별로 지역성을 띄는 문자집합을 만들어 사용했습니다. 예를 들어 EUR-KR(한글), Shitf_JIS(일본어) 등이 있습니다. 그런데 EUR-KR과 같은 인코딩 방식은 한글, 한국에서 통용되는 일부 한자 등을 제외한 다른 나라의 문자나 현재 많이 사용되는 이모티콘, 기호 등을 모두 표현할 수 없는 한계를 벗어나지 못한 방법입니다. 그 문제를 해결하기 위한 최종적인 방법이 유니코드(Unicode)입니다. 유니코드는 전 세계에 존재하는 모든 문자와 이모지, 기호 등을 표현하기 위해 만들어진 문자집합으로 2~3byte를 사용해 문자를 표현합니다. 또한 유니코드 문자는 U+ 기호를 사용하고 그 뒤에 16진수를 붙여 표현합니다.
예를 들어

A -> U+0041, 한 -> U+D55C, 😅 -> U+1F605

와 같이 유니코드로 변환할 수 있습니다.



문자열인코딩

다시 말씀드리지만 인코딩이란 문자를 컴퓨터가 이해할 수 있는 형태로 변환하는 것이라 했습니다. 그럼 문자를 아스키코드로, 문자를 유니코드로 변환하는 것으로 이미 인코딩을 했는데 문자열인코딩은 무엇을 또 인코딩 한다는 걸까요??
쉬운 이해를 위해 위에서 언급한 예제를 다시 한번 보겠습니다.

A -> U+0041, 한 -> U+D55C, 😅 -> U+1F605

'A'는 U+0041, '한'은 U+D55C로 변환됩니다. 이때 유니코드는 2~3byte를 사용하므로 'A' 문자는 앞의 1byte가 필요없지만 빈 공간으로 사용하게 됩니다. 만약 영어 논문을 유니코드로 인코딩해 저장한다고 했을 때 총 사용된 영문자 개수 x 1byte 만큼의 공간 낭비가 발생하게 됩니다.
여기서 UTF-8이라는 문자열인코딩을 한번 더 해주게 되면 이러한 비효율성을 막을 수 있습니다.
UTF-8은 유니코드 한 문자를 나타내기위해 1~4byte를 사용하는 가변 길이 인코딩 방식입니다. 아스키 코드로 표현 가능한 문자의 경우 1byte만으로 표현이 가능한데 여기에 4byte를 할당하는 것은 저장소 낭비가 되므로 1byte만 할당합니다.
UTF-8로 인코딩한다는 것은 문자를 유니코드로 인코딩하고 UTF-8로 문자열인코딩하여 컴퓨터에 저장하는 것입니다.
예를 들어 '한글'이라는 문자를 UTF-8로 인코딩하면

'한글' -> U+D55C, U+AE00(유니코드) -> 0xEC959C, 0xEAB880(UTF-8)

위와 같은 과정을 거쳐 저장됩니다.
요약하자면 이미 변환된 문자를 효율적 또는 원하는 방식으로 저장하기 위해 다시 한번 인코딩하는 것이 문자열인코딩입니다.

인코딩 오류 사례 재현해보기

EUC-KR로 인코딩된 문서를 UTF-8로 열려고 하면??

지금까지 알아본 인코딩 이론을 토대로 처음에 본 인코딩 오류를 재현해보겠습니다. 예를 들어 우리나라에서 많이 쓰이는 한글 인코딩 방식은 EUC-KR로 인코딩된 문서를 생각해보겠습니다.
'한'이라는 글자의 경우

한 -> 0xC7D1(EUC-KR) , 0xEC959C(UTF-8)

로 변환되며 같은 글자임에도 인코딩 방식에 따라 다르게 저장되는 것을 알 수 있습니다. 그렇기 때문에 EUC-KR로 저장된 문자열을 UTF-8로 디코딩하거나 반대의 상황에서 다음과 같은 외계어가 나오는 것입니다.

마무리

문자열인코딩에 대해 어렴풋이 알고는 있지만 항상 자세히 설명하려고하면 어딘가 모르게 막히는 부분이 있었습니다. 문자열인코딩에 관한 내용을 알아보면서 문자집합(charset)과 문자열인코딩를 정확히 구분하고 다음부터는 누가 물어보더라도 자신있게 설명할 수 있었으면 좋겠습니다!

profile
안녕하세요

0개의 댓글