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으로 나타낼 수 있다.
아래를 확인하면 어떤식으로 표현이 되어있는지 확인할 수 있다.

최근댓글