Server programming

03_03_패킷 직렬화_UTF-8 vs UTF-16

devRiripong 2023. 4. 11.
반응형

Q1. Ascii, 유니코드, UTF-8, UTF-16의 특징을 설명해 보세요

유니코드와 인코딩

유니코드는 문자를 고유한 코드 포인트로 매핑하는 규격으로, 컴퓨터가 문자를 이해할 수 있도록 합니다. 인코딩은 유니코드 문자를 바이트로 변환하는 방법입니다. 주요 인코딩 방식에는 UTF-8과 UTF-16이 있습니다.

ASCII 코드

ASCII 코드는 1바이트로 문자를 표현하는 방식입니다. 하지만 다양한 언어를 표현하기에는 한계가 있어, 유니코드가 등장했습니다.

유니코드

유니코드는 2바이트로 대부분의 문자를 표현할 수 있지만, 일부 문자는 3바이트가 필요합니다. 이를 효율적으로 표현하기 위해 가변 길이 인코딩 방식이 등장했습니다.

UTF-8

UTF-8은 가변 길이 인코딩 방식으로, 영문은 1바이트, 한글은 3바이트로 표현됩니다. 영문을 주로 사용하는 경우에 효율적입니다.

UTF-16

UTF-16은 2바이트 영역의 문자를 2바이트로, 추가 영역의 문자를 4바이트로 표현합니다. C#과 언리얼 엔진에서 기본으로 사용됩니다. 영문은 2바이트, 한글과 한자도 2바이트로 표현되므로, 아시아 국가에서는 이점이 있습니다.

유니코드는 공통적이지만, 인코딩 방식에 따라 데이터 표현이 달라집니다. 따라서 클라이언트와 서버 간 통신 시 인코딩 방식을 맞춰야 합니다.

 

Q2. UTF8, UTF16은 유니코드에 포함되는 건가요?

UTF-8과 UTF-16은 유니코드를 인코딩하는 방식입니다. 이들은 유니코드에 직접 포함되지는 않지만, 유니코드 문자를 표현하기 위해 사용되는 인코딩 체계입니다. 유니코드는 문자에 대한 고유한 코드 포인트를 제공하며, UTF-8과 UTF-16은 이러한 코드 포인트를 바이트로 변환하여 컴퓨터에서 처리할 수 있는 형태로 만드는 방법을 제공합니다.

간단히 말해서, 유니코드는 문자의 고유 식별자를 제공하고, UTF-8과 UTF-16은 그 식별자를 바이트로 변환하는 인코딩 방법입니다. 이들 인코딩 체계는 유니코드와 밀접한 관련이 있지만, 유니코드 자체에는 포함되지 않습니다.

 

 

 

 

다음 순서로는 문자열을 Serialization 해서 네트워크 패킷에다 밀어넣는 작업을 해볼거야.

Unicode & Encoding을 훑어 볼거야.

처음 시간에 UTF8로 문자열을 인코딩 해서 네트워크 상으로 보냈었어. UTF8은 무엇인지, 다른 옵션은 무엇인지에 대해 살펴 볼거야.

유니코드 및 인코딩은 결국 문자를 컴퓨터에게 어떻게 이해시킬지에 관한 부분이야.

 

Ascii 코드

역사적으로 오랜 과거로 돌아가보면, 1byte로 문자를 표현했어.

 

A는 65번 16진수로는 0x41

각각 1바이트 숫자로 대응 시켜서 컴퓨터한테 이해를 시키는 것

나중에 컴퓨터 한테 33번이라는 문자를 찍어줘 라고 하면 컴퓨터는 얘가 느낌표라는 걸 알아서 화면에 느낌표를 출력하는 이런 방식으로 동작을 하면 된다.

처음에는 1바이트만으로 모든 문자가 동작을 했는데 근데 각 나라마다 언어가 다르니까 1바이트에 자신만의 언어를 잘 밀어 넣어서 사용을했어. 근데 나중에 인터넷을 통해서 다른 언어로 된 사이트에 접속할 때 문자가 깨져서 읽히는 상황이 발생을 한다.

유니코드

 

결국 유니코드라 해서 온 세상 문자들을 통일 한 규격으로 만드는 작업이 진행이 된건데 1바이트는 255까지 숫자까지 밖에 표현을 할 수 없는데 1바이트 더 늘려서 2바이트면 충분하지 않을까 싶다. 2바이트는 65535라는 굉장히 충분한 공간이 있으니.

2바이트로 문자를 표현하기 시작한게 유니코드의 유래

 

온갖 문자들이 다 들어가 있어.

시간이 흐를 수록 각기 희소성이 있는 언어도 계속 들어가다 보니까 점점 공간이 부족하게 된다.

 

초록색 선 까지가 BMP라고 부를 수 있는 2바이트로 표현할 수 있는 유니코드의 영역

그 다음으로 삐져 나온 것을 볼 수 있다. 3바이트까지 가야 표현할 수 있는 영역이다.

한자, 묘한 음악 심볼 이런 것도 추가됐다.

유니코드는 2바이트가 아니라 정확하게는 3바이트까지 차지를 한다고 생각을 하면 된다.

 

지금까지 3바이트라고 하면 이제 얘를 어떻게 컴퓨터한테 이해를 시킬지 궁금하다.

상식적으로 일단 3바이트 짜리 정수로 넘겨주면 되긴 될거야. 0x000041이라는 16진수 숫자로 넘기면 컴퓨터가 처리할거야. 이게 첫번째 방법이 될거야.

근데 이게 비효율적이라는 생각이 든다.

초반에 있는 0~9 같은 숫자가 많이 사용이 될거야. 뒤로갈수록 나오는 희귀 한자 같은 건 거의 사용할 일이 없음에도 불구하고 걔네들 때문에 굳이 3바이트로 표현하는게 낭비가 될 것이다.

유니코드는 표현하고 싶은 문자랑 걔가 몇 번째 번호인지를 매핑을 한게 유니코드라고 생각하면 된다.

인코딩이란 개념이 들어가는데 걔를 컴퓨터에게 어떻게 알려줄까가 별도로 들어가게 된다.

모든 문자를 3바이트로 표현하는게 아니라 이제 가변적인 방법을 사용한다

UTF-8

 

많이 사용하는게 UTF8, UTF16이 있다.

4바이트로 표시하는 경우는 굉장히 드물다.

일반적 간단한 영문은 1바이트, 한글같은 경우는 3바이트로 표현이 된다.

0~127은 그 냥 1바이트로 표현되고 있다. 빨간색으로 밑줄 친 건 한글이 이 범위에 포함되어 있다.

UTF-8 에서 간단한 영문은 1바이트로 표현이 될거고, 한글 같은 경우는 3바이트로 표현이 될거야.

UTF-8 쓰면 해외권에서 영문 많이 들어간다고 가정을 하면 효율적일 거고, 국내 서비스 하면 한글에 3바이트씩을 사용해야 해서 낭비가 될 거야.

이렇게 장단점이 갈린다. UTF-8은 외국 문자를 우선시한 방법이라고 생각하면 된다.

UTF16

 

간단하다. BMP라고 해서 2바이트 영역까지는 2바이트로 표현을 하고

그 다음에 추가로 있는 부분은 4바이트로 표시를 하는

c#에서 기본적으로 사용하고 있는 것도 UTF16이다.

파일 입출력은 utf8로 하고, char라는 걸 사용하면 C#에서 char 타입이 2바이트 였어.

C++이랑 다른 점이야**. C++**은 일반적인 default char가 1바이트 였지만 C#은 2바이트.

2바이트로 표현하는게 조금 더 합리적인 부분이 있는 건 애당초 유니코드에서 대부분의 문자들은 2바이트에 들어 갔으니까 2바이트로 설정했어.

UTF16으로 작업을 하면 영문도 2바이트, 한글도 2바이트가 된다. 어지간한 중국어 한자도 2바이트에 들어가게 될거야.

그렇다는 건 영문권 기준으로 하면 약간 손해지만 일반적인 중국이나 한국 일본 포함한 일반적 관점에서 보면 UTF16이 조금 더 이점이 있다.

C#뿐만 아니라 언리얼 같은 경우도 default로 UTF-16를 사용하고 있고, 결국 서버를 구현해서 클라와 통신을 할 때는 문자라는 개념이 모호하다.

유니코드는 공통적이지만 얘를 어떤 식으로 인코딩해서 데이터로 들고 있을지는 갈리게 된다 .

그렇기 때문에 UTF8로 할지 UTF16으로 할지 결정을 해서 걔를 맞춰줘야 클라이언트와 정상적인 통신을 할 수 있다.

 

반응형

댓글