유니코드와 UTF-8 사이의 변환

3843 단어 부호화
요 며칠 동안의 연구를 통해 유니코드와 UTF-8 사이의 인코딩의 차이를 마침내 알게 되었다.유니코드는 문자 집합이고 UTF-8은 유니코드의 일종이며 유니코드는 길이가 두 바이트로 정해져 있는데 UTF-8은 가변적이어서 한자로 유니코드가 차지하는 바이트는 UTF-8이 차지하는 바이트보다 한 바이트가 적다.유니코드는 2바이트이고 UTF-8에서는 한자가 3바이트를 차지한다.
참고: 유니코드 인코딩을 위해 현재 계획된 총 공간은 17개의 평면, 0x0000~0x10FFF입니다.평면마다 65536개의 야드 포인트가 있다.그래서 이 총 길이도 백만 개가 넘는다.
UTF-8 인코딩 문자는 이론적으로 최대 6바이트까지 가능하지만, 16비트 BMP(Basic Multilingual Plane) 문자는 최대 3바이트까지만 사용할 수 있습니다.다음은 UTF-8 인코딩 테이블입니다.
 U-00000000 - U-0000007F: 0xxxxxxx
        U-00000080 - U-000007FF: 110xxxxx 10xxxxxx
        U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
        U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
        U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
        U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

xxx의 위치는 문자 인코딩 수의 2진법으로 표시된 위치로 채워져 있으며, 오른쪽에 있는 x일수록 특수한 의미가 적으며, 가장 짧은 문자 인코딩 수를 충분히 표현할 수 있는 다자간 문자열만 사용한다.다중 바이트 문자열에서 첫 번째 바이트의 시작 '1' 의 수는 전체 바이트의 숫자입니다.첫 번째 줄은 0으로 시작하여 ASCII 인코딩을 호환하기 위해 한 바이트이고 두 번째 줄은 두 바이트 문자열이며 세 번째 행위는 세 바이트이다. 예를 들어 한자는 이런 종류에 속한다.(개인적으로는 사실 우리는 앞의 1의 개수를 바이트수로 간단하게 볼 수 있다)
유니코드를 UTF-8로 전환하기 위해서는 이들의 차이가 도대체 어디에 있는지 알아야 한다.유니코드에서 인코딩이 어떻게 UTF-8로 변환되는지 살펴보자. UTF-8에서 한 문자의 바이트가 0x80(128)보다 작으면 ASCII 문자로 한 바이트를 차지하기 때문에 변환하지 않아도 된다. UTF-8은 ASCII 인코딩을 호환하기 때문이다.유니코드에서 한자 '너' 의 인코딩이 'u4F60' 이라면, 2진법으로 100111101100000으로 변환한 다음 UTF-8 방법으로 변환하십시오.유니코드 2진법을 위치에서 높은 위치로 6자리씩 추출할 수 있다. 상기 2진법은 각각 다음과 같은 형식으로 추출할 수 있고 앞쪽은 형식에 따라 채우고 8자리가 부족하면 0으로 채울 수 있다.
unicode: 100111101100000                  4F60
utf-8:    11100100,10111101,10100000       E4BDA0

위에서 보면 유니코드에서 UTF-8 사이의 전환을 직관적으로 볼 수 있다. 물론 UTF-8의 격식을 알게 되면 역연산을 할 수 있다. 바로 격식에 따라 그것을 2진법의 상응하는 위치에서 꺼낸 다음에 변환하면 얻을 수 있는 유니코드 문자이다(이 연산은'위치'로 완성할 수 있다).예를 들어 상술한'당신'의 변환은 0x800보다 크고 0x10000보다 작기 때문에 3자 바이트 저장소로 판단할 수 있다. 그러면 가장 높은 위치는 오른쪽으로'12'위치를 옮겨야 한다. 그리고 3자 바이트 형식의 가장 높은 위치에 따라 11100000(0xE0)을 구하거나 (|)을 구하면 가장 높은 값을 얻을 수 있다.같은 이치로 두 번째는 오른쪽으로'6'자리를 옮기면 가장 높은 자리와 두 번째 자리의 이진법 값이 남는다. 111(0x3F)와 위치(&)를 구하고 11000000(0x80)을 구하거나 (|)를 구할 수 있다.3위는 자리를 옮길 필요가 없다. 마지막 6위(11111(ox3F)와 &)를 직접 취하고 11000000(0x80)과 구하거나 (|)를 구한다.오케이, 전환 성공!VC++의 코드는 다음과 같습니다(유니코드에서 UTF-8로의 변환).
1 const wchar_t pUnicode = L" ";
        2 char utf8[3+1];
        3 memset(utf8,0,4);
        4 utf8[0] = 0xE0|(pUnicode>>12);
        5 utf8[1] = 0x80|((pUnicode>>6)&0x3F);
        6 utf8[2] = 0x80|(pUnicode&0x3F);
        7 utf8[3] = "\0";
        8 //char[4]  UTF-8   “ ” 。

물론 UTF-8에서 유니코드로의 전환도 위치 이동 등을 통해 이루어진다. 바로 UTF-8의 격식에 상응하는 위치의 이진수를 끄집어내는 것이다.상술한 예에서'당신'은 세 바이트이기 때문에 각 바이트를 처리하고 높은 위치에서 낮은 위치로 처리해야 한다.UTF-8에서'당신'은 11100100101110100000이다.높은 위치에서 첫 번째 바이트인 11100100은 그 중의'0100'을 꺼내는 것이다. 이것은 매우 간단하다. 11111(0x1F)과 (&)만 나누면 3바이트로 가장 높은 위치가 12자리 앞에 있다는 것을 알 수 있다. 왜냐하면 매번 6자리를 얻기 때문이다.그래서 얻은 결과를 12위로 왼쪽으로 옮기고 최고위도 이렇게 0100000000000을 완성했다.2위는'111101'을 빼야 하며, 2자 바이트 1011111과 11111(0x3F)를 빼면 된다.얻은 결과를 6위와 최고 바이트로 왼쪽으로 옮기면 (|), 2위는 이렇게 완성되고 얻은 결과는 010011101000000이다.이와 같이 마지막 자리를 11111(0x3F)와 직접 (&) 취하고 앞에서 얻은 결과와 (|) 취하면 0100111101100000의 결과를 얻을 수 있다.오케이, 전환 성공!VC++의 코드는 다음과 같습니다(UTF-8에서 유니코드로 변환). 
 1 //UTF-8      
    2 const char* utf8 = " ";
    3 wchar_t unicode;
    4 unicode = (utf8[0] & 0x1F) << 12;
    5 unicode |= (utf8[1] & 0x3F) << 6;
    6 unicode |= (utf8[2] & 0x3F);
    7 //unicode is ok!

물론 프로그래밍 과정에서 한 문자만 변환할 수 없다. 여기서 주의해야 할 것은 문자의 길이는 반드시 명확하게 계산해야 한다. 그렇지 않으면... 을 가져올 수 있다.이상은 제가 요 며칠 연구한 결과입니다. 유니코드의 전환은 GB2312에서 MFC에서 WideCharTo MultiByte로 전환할 수 있습니다.이렇게 하면 UTF-8 포맷을 GB2312로 바꿀 수 있으니 더 이상 군말하지 않겠습니다. 더 좋은 방법이 있다면 가르쳐 주십시오.

좋은 웹페이지 즐겨찾기