Forensic/Forensic 이론

문자(Characters) 인코딩

Ron Weasley 2021. 12. 24. 23:59

  디지털 데이터의 표현 방법인 문자에 대해서 알아보겠습니다.

문자 인코딩
  인코딩 또는 텍스트 인코딩으로 불리며, 사용자가 입력한 문자나 기호들을 컴퓨터가 이용할 수 있는 2진 신호로 만드는(변환하는) 것을 말합니다. 

  디지털 기기에서 문자는 화면에 출력되는 형태를 결정하는 중요한 요소입니다. 문자는 한글, 영어, 숫자, 특수문자 등을 표현하기 위해 디지털 기기에 문자의 특정 값을 대응시켜 사용하는데 이를 문자 코드라고 칭합니다.

 

  문자 코드는 컴퓨터 시스템마다 서로 다르지만 동일하게 해석이 되어 표준으로 지정되어 있는 문자 코드가 여럿 존재합니다. 그래서 오늘은 표준으로 지정되어 있는 문자 코드중 대표적으로 4가지만 알아보겠습니다.

 

ASCII(아스키) 문자 코드

  ASCII코드는 American Stanard Code for Information Interchange의 약자이며, 미국 표준 협회 ANSI에서 제정한 자료 처리 및 통신 시스템 상호 간의 정보 교환용 표준 코드입니다. ASCII코드는 7비트로 구성되어 있고, 128가지의 기호를 정해 놓음으로써, 1바이트를 가지고 하나의 문자를 표현합니다.

 

  아스키 코드의 128가지 기호의 구성을 보면 33가지의 출력이 불가능한 제어 부호, 그래픽 기호 33가지, 숫자 10가지, 알파벳 대소문자 52가지로 구성되어 있습니다.

 

  하지만 위에서 아스키 코드는 7비트로 구성되어 있다고 했습니다. 하지만 보통 기억장치는 8비트의 조합으로 이루어져 있는데, 아스키는 128개의 문자만 표현을 하기 때문에 남은 1비트는 패러티 비트로 불리는 정보의 전달 과정에서 오류가 생겼는지 확인하는 에러 검출 비트입니다.

 

EBCDIC(엡시딕) 문자 코드

  EBCDIC코드는 Extended Binary Coded Decimal Interchange Code의 약자이며, IBM사에서 사용하는 문자 체계로 IBM에서 개발한 프로그래밍 언어인 Fortran에서 사용했고, 또한 대형 운영체제에서 사용하기 위해 개발한 알파벳 및 수자를 위한 바이너리 코드입니다. 엡시딕 코드는 8비트 코드로 256개의 서로 다른 문자가 정의되어 있습니다.

 

한글 조합형, 완성형, 확장 완성형 문자 코드

  위 문자 코드는한글을 표현하기 위해 만들어 진 문자 코드로써 조합 - 완성 - 확장 순으로 개발이 되었다.

 

1) 조합형 코드

  2바이트 완성형 코드가 발표되기 전까지 사용되었던 코드로, 한글을 초성, 중성, 종성에 맞춰 조합하여 표현이 되었다. 초성은 "ㄱ", "ㄴ", "ㄷ", "ㄹ" 을 표현하고, 중성은 "ㅏ", "ㅑ", "ㅓ", "ㅕ"를 표현하고, 종성은 "ㄱ", "ㄲ", "ㄳ", "ㄴ" 등 마지막에 들어갈 한글을 표현했다. 예를 들어 "밤" 이라는 단어를 표현할 때 조합형 코드로 표현하면 (초성 : "ㅂ", 중성 : "ㅏ", 종성 : "ㅁ") 이렇게 된다. 즉, 자음 14개와 모음 10개의 글자를 조합하여 한글 11,172자를 다 표현하였음에도 불구하고 표준안이 채택되지 않아 완성형 코드가 나온 것 입니다.

 

2) 완성형 코드

  조합형 코드의 확장형으로써 큰 차이점은 글자의 표현능력이다. 조합형 코드의 확장형인데 비해서 표현할 수 있는 갯수는 한글 11,172자 중 2,350자만이 표현이 가능하다. 근데 왜 확장형일까??

 

  의문점을 풀어 드리자면 조합형 코드와 완성형 코드는 코드의 형태에 나뉘었습니다. 조합형은 한글을 표현하기 위해 3바이트를 사용했지만 완성형에서 한글 표현은 연속된 두 개의 바이트를 이용해서 표현했습니다. 완성형의 첫 번째 바이트와 두 번째 바이트 모두 0xA1 ~ 0xFE 사이의 값을 가집니다. 

 

3) 확장 완성형 코드

  Microsoft사가 Windows 95부터 도입한 코드로써, 위 완성형 코드에서 표현이 불가능한 8,822자에 대해서 억지로 채워넣은 코드입니다. 그래서 현대 한글을 모두 표현할 수 있으며, 완성형 코드와 같이 한글을 표현하는데 2바이트를 사용합니다.

 

UNICODE(유니코드)

  유니코드는 전 세계에 존재하는 모든 문자를 컴퓨터에서 일관되게 표현하고 다룰 수 있도록 설계된 산업 표준 코드입니다. 한글은 유니코드 2.0에서부터 11,172자가 모두 포함이 되었고, 유니코드는 31비트 문자 세트이지만, 특수 문자를 제외한 전 세계 모든 문자들은 하위 16비트의 영역 안에 정의되어 있다. 유니코드의 인코딩 방식으로 잘 알려진 코드 포인트를 코드화한 UCS-2, UCS-4와 변환 인코딩 형식(UTF, UCS Transformation Format)인 UTF-8, UTF-16, UTF-32가 있습니다. 이 중 기본적으로 가장 많이 사용하는 것이 UTF-8입니다.

 

1) UCS-2와 USC-4

  유니코드를 메모리나 파일에 기록하는 방법에 따라 UCS-2, UCS-4로 구분할 수 있습니다. 두 개의 차이점은 n바이트를 사용하여 유니코드 문자 세트를 표현하는 것인데, UCS-2는 2바이트를 사용하여 유니코드 31비트 문자 세트 중 16비트 이하의 문자 부분만을 표현하고, UCS-4는 유니코드 31비트 문자 세트 모든 영역을 표현합니다. 이유는 설명 안해도 알다 시피 2바이트는 15개의 문자만을 표현하고 4바이트는 31개의 문자를 표현할 수 있기 때문입니다. (2byte : 16bit, 4byte : 32bit)

 

2) UTF-8

  전 세계적으로 가장 일반적으로 사용하는 유니코드 포맷입니다. 31비트의 유니코드를 1~6개의 바이트에 나누어 저장하는 방식이고, UTF-8 첫 번째 바이트를 읽는 것만으로 몇 개의 바이트로 구성된 것인지 알 수 있습니다. 아스키 코드 영역에 해당하는 문자(알파벳, 숫자)들은 각 1바이트로 표현할 수 있고, 한글을 표현할 때 한 글자당 3바이트로 표현이됩니다. 근데 여기 까지만 보면 UTF-8이 ASCII랑 별 차이없게 느껴질 수 있지만, UTF-8과 ASCII의 큰 차이점은 전 세계적으로 모든 언어를 처리할 수 있다는것이다. 한글뿐 아니라 일본어, 중국어, 영어 등 표현이 가능하다. 대부분 UFT-8 문자열은 기존 인코딩으로 표현한 문자열보다 더 크고, 판독 기호를 사용하는 대부분의 라틴 알파벳 문자는 최소 2바이트를 사용하며, 한국-중국-일본어 문자들은 최소 3바이트를 사용한다. 

 

3) UTF-16

  UTF-8과는 다른 관점에서 생긴것으로써 UCS-2 문자열 안에 유니코드 21비트의 영역의 문자를 표현하기 위해서 도입되었고, 다른 말로 UCS-2의 확장형 이라고 해도 무관하다. UCS-2는 U+D8000 ~ U+DFFF 영역을 정의하고 있지 않은데, UTF-16은 이 영역을 응용하여 두 개의 UCS-2 코드를 조합함으로써 16비트 위의 21비트까지 표현이 가능하다. 예를들어 BMP파일에 들어 있는 한중일 문자들은 UTF-8에서 3바이트로 표현이 되지만, UTF-16에서는 2바이트로 표현이 됩니다. 따라서 UTF-8에서 이러한 문자를 표현하기 위해서는 UTF-16과 비교했을 때, 1.5배이상 크기가 늘어날 수 있다. 

 

UTF-8 과 UTF-16의 차이

똑같은 내용이 담긴 두개의 파일을 보겠습니다. 하나는 UTF-8로 인코딩한 메모장이고 나머지 하나는

UTF-16 BE(Big Endian)으로 인코딩한 메모장입니다. 다음으로 두 텍스트 파일의 속성을 보겠습니다. 

(좌측) UTF-16 && (우측) UTF-8

속성을 보니 같은 문자를 입력했음에도 불구하고 크기가 3바이트가 차이가 나는걸 볼 수 있습니다. 아까 위에서 설명했듯이 UTF-16은 UTF-8보다 최대 1.5배의 크기를 가질 수 있다고 했으니 당연한 결과입니다. 그리고 hex editor로 두 파일을 비교 했을 경우를 살펴봅시다.

COMPARE

위에 61 62 63으로 시작하는것은 UTF-8.txt를 열었을 때 바이너리 값이고, FE FF 00은 UTF-16.txt를 열었을 때 바이너리 값이다. 분명히 UTF-8에서는 우리가 입력한 abcd가 저장된 아스키 코드가 보이고, 그 후로는 한글이 입력 되었으니까 3바이트씩 처리가 되었으니 0D-0A가 엔터키를 뜻하는것으로 알수있고, UTF-16에서는 UTF-8과는 달리 처음 시작부분이 FE, FF로 시작을 하게 되는데 이 부분은 16비트 코드 엔디언을 나타냅니다. 저 부분은 BE로 파일을 저장하게 되면 0xFEFF이고 LE인 리틀엔디안으로 저장을 하게 되면 FFFE이다. 근데 헥스값을 읽을 땐 리틀엔디안 형식으로 읽어야 하기 때문에 BE로 저장하지 말고 LE로 저장하자. (독자는 BE로 저장했다)

 

4) UTF-32

  UTF-32는 문자를 4바이트로 표현한다는 점에서는 UCS-4와 동일하지만, 실질적으로 0x00000000~ 0x0010FFFF 범위로 문자 코드의 범위를 제한하기 때문에 UCS-4의 부분 집합이라고 할 수 있고, 문자 인코딩을 할 때 모든 유니코드 문자를 같은 길이로 인코딩한다.

 

오랜만에 포스팅을 하게 되었는데요...다음 시간에는 문자 인코딩이 아닌 데이터 인코딩인 Base64, Base58을 알아보고 파이썬 코드로 직접 구현하는 방법도 보겠습니다. 다들 즐거운 공부 되시길 바랍니다!

 

참고 블로그

https://nhj12311.tistory.com/59

 

UTF8과 UTF16의 차이

최근엔 개발하면서 UTF8로 통일해서 쓰지만 십년 전 정도에는 euc-kr로 구성된 시스템이 많아서 이기종 간 데이터 통신 시에 문자 인코딩 방식이 달라서 애를 먹은 적이 많다. 실제 개발할 때 이기

nhj12311.tistory.com

 

'Forensic > Forensic 이론' 카테고리의 다른 글

해쉬 함수 (Hash Function)  (0) 2022.01.20
데이터 인코딩(Data Encoding)  (0) 2022.01.18
디지털 데이터의 수 체계  (0) 2021.07.24
디지털 데이터의 구성 단위  (0) 2021.07.04
디지털 포렌식의 유형  (0) 2021.06.23