Используйте существующую утилиту, например iconv , или любые другие библиотеки, поставляемые с языком, который вы используете.
Если вы настаиваете на развертывании своего собственного решения, ознакомьтесь с форматом UTF-8 . По сути, каждая кодовая точка хранится как 1-4 байта, в зависимости от значения кодовой точки. Диапазоны следующие:
- U + 0000 - U + 007F: 1 байт: 0xxxxxxx
- U + 0080 - U + 07FF: 2 байта: 110xxxxx 10xxxxxx
- U + 0800 - U + FFFF: 3 байта: 1110xxxx 10xxxxxx 10xxxxxx
- U + 10000 - U + 10FFFF: 4 байта: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
Где каждый х - бит данных. Таким образом, вы можете определить, сколько байтов составляет каждую кодовую точку, посмотрев на первый байт: если он начинается с 0, это 1-байтовый символ. Если это начинается с 110, это 2-байтовый символ. Если он начинается с 1110, это 3-байтовый символ. Если он начинается с 11110, это 4-байтовый символ. Если он начинается с 10, это не начальный байт многобайтового символа. Если он начинается с 11111, это недопустимый символ.
После того, как вы выясните, сколько байтов в символе, это просто вопрос, если немного перемешать. Также обратите внимание, что UCS-2 не может представлять символы выше U + FFFF.
Поскольку вы не указали язык, вот несколько примеров кода C (проверка ошибок не указана):
wchar_t utf8_char_to_ucs2(const unsigned char *utf8)
{
if(!(utf8[0] & 0x80)) // 0xxxxxxx
return (wchar_t)utf8[0];
else if((utf8[0] & 0xE0) == 0xC0) // 110xxxxx
return (wchar_t)(((utf8[0] & 0x1F) << 6) | (utf8[1] & 0x3F));
else if((utf8[0] & 0xF0) == 0xE0) // 1110xxxx
return (wchar_t)(((utf8[0] & 0x0F) << 12) | ((utf8[1] & 0x3F) << 6) | (utf8[2] & 0x3F));
else
return ERROR; // uh-oh, UCS-2 can't handle code points this high
}