문자 인코딩, 문자셋, 유니코드 2020. 05. 01. 13:49 study/gardenist#javascript#character set#charset#unicode#utf-8 컴퓨터는 결국 0과 1로 표현됩니다. 우리가 컴퓨터를 사용하면서 보는 글자, 이미지, 파일 등도 어떤 방식으로든 0과 1로 저장이되거나 전송이 됩니다. 그래서 0과 1로 변환하는 것을 인코딩(Encoding, 부호화)이라고 하며, 이 중 글자를 0과 1로 변환하는 것을 문자 인코딩(Character Encoding)이라고 합니다. 문자 인코딩과 문자 셋 위키피디아의 부호화 문서에는 아래와 같이 정의되어 있습니다. 부호화 또는 인코딩(encoding)은 정보의 형태나 형식을 표준화, 보안, 처리 속도 향상, 저장 공간 절약 등을 위해서 다른 형태나 형식으로 변환하는 처리 혹은 그 처리 방식을 말한다. 문자 부호화에 맞게 각색해서 다시 정의해보면 “문자 부호화 또는 문자 인코딩은 문자를 저장하거나 처리하기 위한 변환 혹은 그 변환 방법을 말한다.”로 볼 수 있습니다. 컴퓨터에 맞게 한글 인코딩 방법을 아주 간단한 예를 들어보면 이와 같이 정의해볼 수 있습니다. “2개의 byte를 사용해 자음 ㄱ은 0x0000, ㄴ은 0x0001, ㄷ은 0x0002 와 같이 변환한다.” 인코딩의 반대는 디코딩(복호화)이라고 하며, 위의 정의에서 우리는 0x0000을 디코딩하면 ㄱ이 되는 것을 알 수 있습니다. 문자 셋(문자 집합, Character set, Charset)은 문자들의 집합을 정의한 것으로 문자 셋에서 다루는 문자에 음수가 아닌 정수들을 배정한 것을 부호화된 문자 셋(coded character set, CCS)라고 합니다. ASCII, EUC-KR, UTF-8 등 대개의 문자 셋들은 부호화된 문자 셋에 해당하며, 일반적으로 문자 집합과 문자 인코딩은 어떤 문자를 사용할 수 있으며 어떤 식으로 표현되는지를 나타낸다는 점에서 동의어로 취급되기도 합니다. (위키피디아 문자 인코딩) 유니코드 컴퓨터가 개발된 초기에는 여러 나라의 문자를 다룰 필요성이 크지 않았지만(ASCII만 해도 1963년에 표준화 초판이 발간되었음) 점차 표준화된 다국어 표현을 위해 유니코드가 개발되었습니다. 유니코드(Unicode)는 전 세계의 모든 문자를 컴퓨터에서 일관되게 표현하고 다룰 수 있도록 설계된 산업 표준이며, 유니코드 협회(Unicode Consortium)가 제정한다. (중략) 유니코드의 목적은 현존하는 문자 인코딩 방법들을 모두 유니코드로 교체하려는 것이다. 기존의 인코딩들은 그 규모나 범위 면에서 한정되어 있고, 다국어 환경에서는 서로 호환되지 않는 문제점이 있었다. 유니코드가 다양한 문자 집합들을 통합하는 데 성공하면서 유니코드는 컴퓨터 소프트웨어의 국제화와 지역화에 널리 사용되게 되었으며, … (위키피디아 유니코드) 이러한 유니코드는 1988년에 초안이 발간되어 1991년 10월에 한글이 포함되었습니다. 이후 1996년 7월 2.0 버전에 11,172자의 새 한글 완성자 영역을 새로 지정하였습니다. 유니코드는 유니코드 평면이라는 유니코드 전체를 논리적으로 나눈 범위를 정의하고 있으며, 0번에서 16번까지 모두 17개의 유니코드 평면으로 나뉘며, 각 평면은 65536개(2의 16제곱)의 코드로 구성됩니다. 그 중 첫 번째인 0번 평면은 다국어 기본 평면(Basic multilingual plane, BMP)으로 U+0000부터 U+FFFF까지의 영역을 차지합니다. 다국어 기본 평면에는 거의 모든 근대 문자와 특수 문자가 포함되어 있으며, 그 중 대부분은 한글과 한중일 통합 한자들로 이루어져 있습니다. <위키피디아 - 다국어 기본 평면> - 한 칸은 문자 256개를 나타냅니다. 유니코드에 할당된 문자의 값을 표현하기 위해서는 코드 포인트(code point)를 사용하고 U+를 붙여서 표시합니다. ‘가’의 유니코드 값은 U+AC00과 같이 표기합니다. 자바스크립트에서는 문자열 내에서 ‘\uAC00’과 같이 표현하기도 합니다. 이러한 코드 포인트를 인코딩하기 위한 방법으로 유니코드 변환 형식(Unicode Transformation Format, UTF) 인코딩과 국제 문자 세트(Universal Coded Character Set, UCS) 인코딩이 있습니다. 즉 UTF-8과 같은 문자셋은 유니코드 코드 포인트를 인코딩하기 위한 방법 중 하나입니다. UTF를 유니코드와 동의어로 쓰는 경우가 간혹 있는데 유의하도록 합시다. UTF-8 UTF-8은 유니코드를 위한 가변 길이 문자 인코딩 방식 중 하나로 Universal Coded Character Set + Transformation Format - 8-bit의 약자입니다. “가변 길이”란 한 글자를 표현하기 위해 정해진 바이트를 사용하는 것이 아니라 변할 수 있는 길이를 의미하며, UTF-8 인코딩은 유니코드 한 문자를 나타내기 위해 1바이트에서 4바이트를 사용합니다. 영문자와 같이 U+0000부터 U+007F 범위에 있는 문자들은 1바이트만 사용하며, 대부분의 문자는 2~3바이트를 사용하며, 4바이트로 표현되는 문자는 모두 다국어 기본 평면(BMP) 바깥의 유니코드 문자이며 거의 사용되지 않습니다. UTF-8의 구조 한글 ‘가’의 경우 유니코드 코드 포인트 U+AC00이고, 이를 이진수로 표현하면 1010110000000000이 됩니다. AC00은 000800-00FFFF 범위에 들어가므로 3개의 바이트를 사용하게 되고, 1110xxxx 10xxxxxx 10xxxxxx 과 같은 형태로 인코딩되어, x부분에 이진수 값을 대체하면 됩니다. 즉 x자리에 1010-110000-000000을 채워주면 ‘가’는 UTF-8로 인코딩했을 때 11101010 10110000 10000000 이 됩니다. UTF-16 UTF-16(16-bit Unicode Transformation Format)은 UTF-8과 마찬가지로 유니코드 문자 인코딩 방식의 하나입니다. 기본 다국어 평면(BMP)에 속하는 문자들은 그대로 16비트 값으로 인코딩이 되고, 그 이상의 문자는 특별히 정해진 방식으로 32비트로 인코딩이 됩니다. UTF-8은 기본 다국어 평면에 속하는 글자도 1~3바이트로 길이가 달라질 수 있었지만 UTF-16은 기본 다국어 평면의 글자는 모두 2바이트로 표현됩니다. UTF-8에서 ‘가’는 11101010 10110000 10000000이었지만, UTF-16에서의 ‘가’는 10101100 00000000입니다. UTF-16에서 유의할 점은 엔디언입니다. 엔디언이란 연속된 값을 배열하는 순서를 의미하며, 바이트의 배열 순서(Byte order)를 지칭할 때 사용하는 용어입니다. 큰 단위가 앞에 나오는 빅 엔디언(Big-endian, BE), 작은 단위가 앞에 나오는 리틀 엔디언(Little-endian, LE)으로 나눌 수 있으며 이 외에 미들 엔디언이 있습니다. 빅 엔디언은 사람이 숫자를 쓰는 것과 같이 큰 수가 앞쪽에 작은 수가 뒷쪽에 오는 방식이고 리틀 엔디안은 그 반대입니다. 예를 들어 10진수 12345는 빅 엔디언으로 쓰여있지만, 이를 리틀 엔디언으로 쓰면 54321이 됩니다. 마찬가지로 한글 ‘가’는 코드 포인트가 U+AC00으로 바이트로 나눠보면 AC와 00입니다. 이 경우 빅 엔디언으로는 AC00이 되고, 리틀 엔디언으로는 00AC가 됩니다. 이를 UTF-16에 적용해 보면 한글 ‘가’는 빅 엔디언 UTF-16(UTF-16BE)으로는 10101100 00000000 이고, 리틀 엔디언(UTF-16LE)로는 00000000 10101100이 됩니다. 빅 엔디언인지 리틀 엔디언인지 구분을 위해 BOM(Byte Order Mark, 바이트 순서 표시)를 사용하는 경우가 간혹 있습니다. BOM은 필수 사항은 아니며, BOM을 쓰려면 텍스트의 시작 부분에 나와야 합니다. (예 - 텍스트 파일의 가장 첫 부분에 BOM 코드가 들어감). BOM은 유니코드에 U+FEFF로 정의되어 있습니다. UTF-16에서의 빅 엔디언 BOM은 FE FF이고, 리틀 엔디언은 FF FE입니다. BOM 문자는 가끔 필요할 수 있지만, 보이는 글자가 아니라서 사람이 식별할 수 없고(BOM이 있어도 텍스트 에디터 등으로 파일을 열어도 표시되지 않습니다.) 텍스트 파일을 읽거나, 네트워크로 텍스트를 전송할 때 문제가 될 수 있으므로 유의해야 합니다. References 해시넷 - 인코딩 위키피디아 - 문자 인코딩 위키피디아 - 유니코드 위키피디아 - UTF-8 위키피디아 - UTF-16 위키피디아 - 엔디언 위키피디아 - BOM Naver D2 - 한글 인코딩의 이해 1편: 한글 인코딩의 역사와 유니코드 Naver D2 - 한글 인코딩의 이해 2편: