[CS] 아스키코드(ASCII), 유니코드(Unicode), UTF-8 에 대해 - 컴퓨터 내부의 언어 체계

2021. 7. 31. 16:34Computer Science

반응형

최근에 "한 권으로 읽는 컴퓨터 구조와 프로그래밍"이라는 책을 읽는 중이다. 내용이 굉장히 알차다. 제목 그대로 컴퓨터의 구조와 내부에서 어떻게 일을 처리하는지 등등.

평소에 스스로 CS 쪽 지식이 부족하다고 느껴 관련해 인강을 듣거나 운영체제 책을 사서 읽었는데, 컴퓨터 구조 쪽은 따로 공부해본 적이 없어서 이번 기회에 책을 통해 공부해보려고 한다. 매일 조금씩 공부한 내용들을 모아 일주일에 한 번씩 이렇게 글로 정리해 올리려고 한다. 

 

오늘은 책의 <1장. 컴퓨터 내부의 언어 체계> 중 컴퓨터에서 텍스트를 표현하는 방법에 대해 정리하려고 한다.

 


 

컴퓨터는 어떻게 말할까? 우리나라 사람들은 한글을 사용해 소통하는데, 컴퓨터는?

컴퓨터는 비트를 사용해 말한다. 즉, 컴퓨터는 비트 체계를 통해서만 소통할 수 있어! 

'비트'라는 단어는 2진법을 사용한다는 뜻의 'binary'와 숫자를 뜻하는 'digit'가 합쳐진 말이다. 

비트는 2진법을 사용한다. 2진법이란? 01, 110 등과 같이 0과 1을 사용해서만 수를 표현하는 진법.

 

텍스트 표현

그래 컴퓨터는 항상 비트를 다루고, 비트를 통해 수와 같은 대상을 표현한다. 그렇다면 우리가 쓰는 문자들(text) 는 어떻게 표현할까? 

아스키코드 (ASCII) 

컴퓨터는 아스키 코드 라는 것을 통해 텍스트를 표현한다.

ASCII는, American Standard Code for Information Interchange( 미국 표준 코드)의 준말로, 키보드에 있는 모든 기호에 대해 7비트 수 값을 할당한다. 

 

예를 들어,

  • A : 10진수로 65, 16진수로 0x41
  • B : 10진수로 66
  • a : 10진수로 97

여기서, '어? 왜 A 가 65라는 숫자로 표현되는거에요?' 라고 물으면,, 할 말이 없다. 이건 약속이다. 어떤 원리를 통해 나오는 값이 아닌 약속이다. 이렇게 표현할 거야~라는 약속. 

 

아래는 아스키 코드 표이다. 

아스키 코드 표

 

위 표를 보면 NUL, SOH, STX와 같은 문자들이 보이는데, 이런 코드들은 글자를 출력하는 데 쓰이지 않고 장치를 제어하기 위해 쓰이기 때문에 제어 문자(Control Character) 라고 불린다. (위 표에 보면 카키색으로 되어 있는 것들이 제어 문자)

이 중 상당수는 통신 제어를 위한 문자다. 예를 들어,

  • ACK(수신 확인, acknowledge)는 '메시지를 받았음'이라는 뜻
  • NAK(반수신 확인, negative acknowledgment)는 '메시지를 받지 못했음'

 

다른 표준의 진화

비트 가격이 떨어짐에 따라 유니코드(Unicode)라는 새로운 표준이 만들어졌고, 문자에 16비트 코드를 부여했다고 한다. 

유니코드가 생긴 당시에는 16 비트면 지구 상에 있는 모든 문자를 다 담고도 여분이 남으리라 생각했다. 그 후 유니코드는 21비트(그중 1,112,064가지 값이 문자를 표현한다)까지 확장됐으며, 그 정도면 앞으로 모든 문자를 다 표현할 수 있을 것이다. 

 

유니코드 변환 형식 8비트 (UTF-8)

컴퓨터는 7 비트 값을 처리하도록 설계되지 않았기 때문에 8비트를 사용해 아스키 문자를 저장한다. 이 경우도 과거에 비해 비트가 훨씬 더 저렴해졌지만 8비트만 사용하면 모든 문자를 표현할 수 있는데 굳이 16비트를 사용해 낭비해도 될 만큼 비트가 저렴하지는 않다는 이유로 한 문자를 8비트로 표현한다.

유니코드는 문자 코드에 따라 각기 다른 인코딩을 사용해 이런 문제를 해결한다. 인코딩(encoding)은 다른 비트 패턴을 표현하기 위해 사용하는 비트 패턴을 뜻한다.

유니코드 변환 형식 8비트(UTF-8, Unicode Transformation Format-8 bit)라는 인코딩 방법이 하위 호환성과 효율성 때문에 가장 널리 쓰이고 있다. UTF-8은 모든 아스키 문자를 8비트로 표현하기 때문에 아스키 데이터를 인코딩할 때는 추가 공간이 필요하지 않다. 

UTF-16은 16비트로 된 유니코드 변환 형식, UTF-32는 32비트로 된 유니코드 변환 형식!

 

개발하다 보면 UTF-8 단어를 많이 듣게 되는데, 예전에 관련해서 애를 먹은 적이 있었다. 예전에 개발해놓은. java 파일을 다른 컴퓨터 환경에서 ecllipse였나? IDE로 java 파일을 열었더니 코드가 다 깨지는 것이다... 이걸 해결하기 위해 인코딩 방식을 utf-8 인가로 바꾸었더니 잘 보였던 기억이 있지.. UTF-8에서 8이 비트를 의미했다니.. 항상 무서운 존재(?) 어려운 존재로 생각했는데 이런 의미였다니!

 

UTF-8 인코딩 방법 

UTF-8은 문자를 8비트 덩어리(이를 octet이라고 부름) 모음으로 인코딩한다.

각 비트 덩어리 앞에 들어가는 값들은 아래 표와 같이 정해져 있다. 이렇게 하면 덩어리의 맨 앞을 식별하기 쉽다는 데 있다. 프로그램이 문자 경계를 찾아야 하는 경우 이런 특성이 아주 유용하다.

출처: 위키피디아 

 

예를 들어, 인코딩하려는 문자의 유니코드 값이 7비트 내로 표현되어, 8비트 덩어리 1개만 필요하다. 이 경우에는 이 덩어리의 첫 번째 값은 무조건 0 이 들어간다. 위 표와 같이! 

이렇게 말로만 설명하면 절대 이해 못한다 ㅠㅠ 너무 어렵거든,, 아래 변환 예시를 보자. 유니코드 -> UTF-8로 변환하는 예시.

위 예제를 보면, UTF-8 은 8비트 덩어리들의 모음으로 표시된 걸 확인할 수 있다. 그리고 각 덩어리들의 가장 앞에 값은 위위의 표에서 정해진 규칙대로 10, 110 등의 값이 고정되어 있는 것도 확인할 수 있다.

 

모든 아스키 문자는 7비트에 들어가기 때문에 덩어리를 하나만 사용해 표현할 수 있다. 영어의 경우, 비 아스키 기호를 사용하는 언어보다 더 적은 용량으로 문자를 인코딩할 수 있기 때문에 영어 사용자에게는 이런 특성이 아주 편리하다.

 


Reference

 

다음에는 Base64 인코딩에 대한 글을 올리려고 한다.

 

반응형