UTF-8 인코딩 방법

유니코드의 종류에는 UTF-8 및 16, 32가 존재한다고 한다.

 

유니코드 표 중 일부

UTF-16과 32는 빅 엔디안 및 리틀 엔디안으로 인코딩이 되는데 UTF-8은 어떤식으로 인코딩이 되는지 찾아보았고 유튜브에 관련된 내용을 듣고 정리하게 되었다.

 

이분의 설명이 매우 자세하고 쉽게 가르쳐 주신다 

UTF-8의 인코딩 방법

 

예를 들어 (유튜브에서 가져온 내용이다)

 

11110000 10011111 10001101 10001110

00101011 11001111 10000000 00100001

과 같은 UTF-8로 인코딩된 바이너리가 있다고 하자.

 

위의 바이너리를 해석하기 위해서는 어떻게 해야 할까?

 

그러기 위해서는 BOM (Byte Order Mark)를 이해해야 한다.

BOM은 데이터 값 앞에 특정 비트를 넣은 다음 이것을 해석해서 정확히 어떤 인코딩 방식으로 (UTF-8, 16, 32 등) 사용되었는지 알아내는 방법을 지칭한다. 그래서 데이터 바이트 앞에는 약속된 비트들이 작성되어 진다.

 

UTF-8을 ENCODING 하기 위한 (BOM)약속은 다음과 같다.

1. 1바이트만 쓰는 경우 - 데이터 앞에 0을 붙인다 (ASCII와 같은 방식으로 표현된다)

2. 2바이트만 쓰는 경우 - 데이터 앞에 110을 붙인다

3. 3바이트만 쓰는 경우 - 데이터 앞에 1110을 붙인다

4, 4바이트만 쓰는 경우 - 데이터 앞에 11110을 붙인다

 

+ 2,3,4 번의 바이트를 쓰는 경우 첫번째 바이트 이후 바이트는 앞에 10을 붙인 바이트가 따라온다.

 

빠르게 예를 해석해보자

 

1. 11110000 10011111 10001101 10001110 

 

11110 이 왔으므로 4바이트를 쓰는 경우이다. 그리고 후행 바이트들은 10을 달고 있으므로 11110에 종속된 데이터들임을 알 수 있다. 

 

그렇다면 밑줄친 부분을 제외하고 남은 데이터들을 합치면

 

(데이터 값) 0 0001 1111 0011 0100 1110 → U+01F34E(사과 이모티콘) 이 된다.

 

 

2. 00101011

 

앞자리에 0이 있으니 1바이트를 쓰는 경우이다. 

 

앞자리를 제외한 데이터 값은 (데이터 값) 0101011 → U+002B

 

 

3. 11001111 10000000 

 

110이 있으니 2바이트의 값이다 

 

(데이터 값) 011 1100 0000 → U+03C0

 

 

4. 00100001 

 

마지막으로 1바이트의 값 U+0021

 

모든 데이터를 더하면

 

사과(이모지) + 파이(이모지) !  가 도출된다.

 

데이터 결과값

 

위와같은 방법으로 하면 UTF-8인코딩 방법을 쉽게 이해할 수 있을거라 생각한다.

 

+ MS 공식문서에 있는 예제

 

Encoding.BigEndianUnicode Property (System.Text)

Gets an encoding for the UTF-16 format that uses the big endian byte order.

docs.microsoft.com

class Program
    {
        public static void Main()
        {

            // The characters to encode:
            //    Latin Small Letter Z (U+007A)
            //    Latin Small Letter A (U+0061)
            //    Combining Breve (U+0306)
            //    Latin Small Letter AE With Acute (U+01FD)
            //    Greek Small Letter Beta (U+03B2)
            //    a high-surrogate value (U+D8FF)
            //    a low-surrogate value (U+DCFF)
            char[] myChars = new char[] { 'z', 'a', '\u0306', '\u01FD', '\u03B2', '\uD8FF', '\uDCFF' };

            // Get different encodings.
            Encoding u7 = Encoding.UTF7;
            Encoding u8 = Encoding.UTF8;
            Encoding u16LE = Encoding.Unicode;
            Encoding u16BE = Encoding.BigEndianUnicode;
            Encoding u32 = Encoding.UTF32;

            // Encode the entire array, and print out the counts and the resulting bytes.
            PrintCountsAndBytes(myChars, u7);
            PrintCountsAndBytes(myChars, u8);
            PrintCountsAndBytes(myChars, u16LE);
            PrintCountsAndBytes(myChars, u16BE);
            PrintCountsAndBytes(myChars, u32);
        }

        public static void PrintCountsAndBytes(char[] chars, Encoding enc)
        {

            // Display the name of the encoding used.
            Console.Write("{0,-30} :", enc.ToString());

            // Display the exact byte count.
            int iBC = enc.GetByteCount(chars);
            Console.Write(" {0,-3}", iBC);

            // Display the maximum byte count.
            int iMBC = enc.GetMaxByteCount(chars.Length);
            Console.Write(" {0,-3} :", iMBC);

            // Encode the array of chars.
            byte[] bytes = enc.GetBytes(chars);

            // Display all the encoded bytes.
            PrintHexBytes(bytes);
        }

        public static void PrintHexBytes(byte[] bytes)
        {

            if ((bytes == null) || (bytes.Length == 0))
            {
                Console.WriteLine("<none>");
            }
            else
            {
                for (int i = 0; i < bytes.Length; i++)
                {
                    Console.Write("{0:X2} ", bytes[i]);
                }
                Console.WriteLine();
            }
        }
    }

위 코드의 결과 값

위를 실행하면 

 

\u0306 이 UTF-8로 인코딩 되면 CC 86으로 변환이 된다

 

바이너리로 보자면 

11001100 10000110 이다

 

위에서 설명한 방식으로 해석을 하면

11001100 10000110 -> 밑줄을 제외한 나머지는 0011 0000 0110 으로 U+0306으로 나타낼 수 있다.

 

아래를 확인하면 어떤식으로 표현이 되어있는지 확인할 수 있다.

 

https://www.fileformat.info/info/unicode/char/0306/index.htm

 

728x90
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기