새소식

AI 개발

[Python] 인코딩 정리

  • -

https://medium.com/@YuriD4/json-encoding-and-decoding-swift-4-c106d7b3c2bd

 

자연어 처리를 하다보면 인코딩에 대해 아는 것이 생각보다 중요해서

정리 한번 하고 넘어가고 싶어서 오랜만에 글을 써봅니다.

 

쓴다고 깔짝 정리해논게 많은데 요즘 생각할게 너무 많아서 포스팅에 게을러진 점 반성합니다 (_ _)

 

 

문자 인코딩(character Encoding)

 

먼저 인코딩이라는 것은 '정보의 형태나 형식을 변환하는 처리 또는 처리 방식'을 뜻한다. 인코딩은 문자 뿐 아니라 사진, 영상 등 다른 데이터 포맷에도 사용된다.

그 중 문자 인코딩은 글자를 어떤 코드표로 매핑시켜놓은 것을 말한다. ex) '갸' -> 98398492839

어떤 데이터를 받고 내 컴퓨터에서 열어봤는데 꿿휄쉙ㅇ!? 처럼 문자가 깨져서 온 적이 있을 것이다. 이는 상대방이 보낸 데이터의 인코딩 방식과 내 컴퓨터에서 설정된 인코딩 방식이 달랐기 때문이다. 

인코딩이 다르다는 것은 표현하려는 동일한 문자에 대해 매핑된 코드표의 값(ID)이 다르다는 것을 의미한다.

 

그렇다면, 왜 하나로 통일하지 않고 ANSI, UTF-8 처럼여러 인코딩을 두는 것일까?

 

이유는 데이터를 전송할 때 데이터의 크기를 줄여 최대한 빠르게 저장할 수 있게 하기 위함이라고 한다.

컴퓨터의 물리적인 공간은 한정적이고 데이터를 보낼 때 컴퓨터가 연산할 수 있는 양, 네트워크로 전송할 수 있는 양은 최대한 줄이는 것이 좋기 때문이다. 예로 UTF-16과 UTF-8의 크기 차이를 들 수 있겠다. UTF-8은 8이 붙은 것 처럼 문자를 표현하는데 8bit(1byte)가 소요된다. UTF-16은 16bit(2byte)를 차지한다.

 

utf-16be vs utf-8

 


 

인코딩의 종류

찾다보니까 너무 많아서(링크) 대표적인 것만 설명하자면 ASCII, CP949, 유니코드, ANSI, UTF-8, UTF-16, EUC-KR이 있다.

 

 

  • 유니코드(Unicode)

종종 유니코드가 특정 인코딩 방식이라는 착각을 하지만 단지 위에서 설명한 코드표 중에 하나를 의미한다. 유니코드는 전세계의 모든 글자를 하나의 코드표로 표현하였기 때문에 가장 범용적인 코드표이다.

많이 사용하는 인코딩 방식 중 하나인 UTF(Unicode Transformation Format)은 유니코드표를 사용한 인코딩 방식이다.

윈도우와 자바에서는 UTF-16방식을 사용하고, 나머지는 거의 UTF-8을 사용한다. 목적에 맞는 인코딩이 필요하지 않다면 대부분 utf-8을 설정해놓는 것이 좋다.

 

유니코드 평면

 

유니코드 평면

유니코드 표는 U+0000 부터 U+FFFF 까지는 Basic Multilingual Plane(BMP),

U+10000 부터 U+1FFFF 까지는 Supplementary Multilingual Plane(SMP)을 의미한다. (그 외에도 더 있음)

BMP에는 기본 다국어 평면을 의미하고,

SMP는 보조 다국어 평면으로 옛 문자나 음악 기호, 수학 기호 등에 쓰인다.

 

 

  • ASCII(American Standard Code for Information Interchange)

아스키(ASCII)는 미국에서 정의한 표준화 부호체계로 7bit, 128개의 고유 값만 사용한다. (1bit는 통신 에러 검출용으로 사용)

 

 

  • ANSI

ASCII의 7비트로 다양한 언어를 할당하기에는 부족해서 8비트로 확장한 것이 바로 ANSI.

아스키는 7비트로 2^7 -> 128개 문자를 표현할 수 있었다면,

ANSI는 2^8 -> 256개 문자를 표현할 수 있었다. 

 

ANSI도 유니코드 처럼 특정 인코딩 방식 하나를 말하는 것이 아닌 특정 코드표를 가르킨다.

유니코드가 전세계 모든 문자를 코드표와 매핑 시킨것과 달리 ANSI는 각 CodePage마다 코드표가 따로 있다.

인코딩 방식 중  euc-kr, cp949가 한글에 대응되는 CodePage이다.

한글을 인코딩 하기 위해서는 cp949와 utf-8, euc-kr 중 하나를 사용하는데,

utf-8을 선택하면 유니코드 코드표에 매핑되고,

cp949를 선택하면 ansi Codepage에 매핑된다. 따라서 메모장에서 ANSI를 선택하면 cp949로 인코딩 되는 것이다.

 

 

 

  • Python Encoding
print(type('가나다라'))
print('가나다라'.encode('utf-8'))
print(type('가나다라'.encode('utf-8')))

# 결과
# <class 'str'>
# b'\xea\xb0\x80\xeb\x82\x98\xeb\x8b\xa4\xeb\x9d\xbc'
# <class 'bytes'>

 

파이썬에서는 기본 문자열이 유니코드고 유니코드를 제외한 나머지 인코딩된 문자는 바이트로 표현된다.

문자를 특정 코드로 인코딩할 때는 encode() 함수를 사용하면 된다. 

다른 인코딩 값의 데이터를 받아서 문자가 깨진다면 내 시스템의 인코딩으로 변환해주면 된다.

 

print(ord('가'))
print(chr(44032))

# 결과
# 44032
# 가

특정문자의 유니코드 값을 보고 싶으면 ord()함수를 이용하고, 유니코드 값을 문자로 보고 싶으면 chr()을 이용하면 된다.

 

import sys

sys.stdin.encoding # 'UTF-8'

그리고 현재 시스템의 인코딩이 뭔지 알고 싶을 때는 위와 같이 확인이 가능하다.

 


 

인코딩 방식

 

  • UTF-8

한 글자를 8bit(1byte)로 표현하는 인코딩 방식이고 한 문자를 표현할 때 1-4bytes의 가변 길이 인코딩 방식(Variable-width encoding)이다. 가변길이 방식을 사용하기 때문에 효율적이고 가장 널리 쓰이는 인코딩 방식 중 하나이다.

 

 

  • UTF-16

한 문자를 나타내는데 2 또는 4 바이트를 사용하는 가변 길이 인코딩 방식이다.

대부분의 문자가 BMP에 속해서 2바이트만 사용하지만 BMP가 넘어가는 경우(U+10000이상) 문자 값을 10비트씩 쪼개서 하위 10비트에 끼워넣는 방식으로 4바이트를 표현한다.

 

  • EUC-KR

아스키와 ANSI는 각 7비트 8비트로 한 문자를 표현하는데 한글은 2byte를 표현하며,

이렇게 표현하는 인코딩 방식을 euc-kr이라고 한다. 가변길이 인코딩 방식이다.

 

  • CP949

EUC-KR의 superset(확장)이며 euc-kr에서 표현할 수 없는 한글도 표현할 수 있다.

따라서 cp949를 euc-kr로 인코딩 할 수 있지만, euc-kr을 cp949로 인코딩 하는 것은 안된다.

 

 

 

 


References

 

whatisthenext.tistory.com/103

yhyacinth.github.io/general/2015/05/18/learn-about-unicode.html

ko.wikipedia.org/wiki/%EB%AC%B8%EC%9E%90_%EC%9D%B8%EC%BD%94%EB%94%A9

umbum.dev/328

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.