Конвертировать символы из UTF-8 в ISO-8859-1 вручную - PullRequest
2 голосов
/ 26 октября 2011

У меня есть персонаж "ö".Если я посмотрю в эту таблицу UTF-8 , то у нее будет шестнадцатеричное значение F6.Если я загляну в таблицу Unicode , то у "ö" будут индексы E0 и 16.Если я добавлю оба, я получу шестнадцатеричное значение кодовой точки F6.Это двоичное значение 1111 0110.

1) Как мне перейти от шестнадцатеричного значения F6 к индексам E0 и 16?
2) Я не знаю, какперейти от F6 к двум байтам C3 B6 ...

Поскольку я не получил результатов, я попытался пойти другим путем.«ö» в ISO-8859-1 обозначается как «¶».В таблице UTF-8 я вижу, что «Ã» имеет десятичное значение 195, а «¶» имеет десятичное значение 182.В битах это 1100 0011 1011 0110.

Процесс:

  1. Посмотрите в таблицу и получите Unicode длясимвол "ö".Рассчитав из индексов E0 и 16 вы получите Unicode U+00F6.

  2. В соответствии с алгоритмом, опубликованным wildplasser, вы можете рассчитать кодированное значение UTF-8 C3 и B6.

  3. Вдвоичную форму вы получите 1100 0011 1011 0110, что соответствует десятичным значениям 195 и 182.

  4. Если эти значения интерпретируются как ISO 8859-1 (только 1 байт), тогда вы получите "ö".

PS: я также нашел эту ссылку , которая показывает значения из шага 2.

Ответы [ 2 ]

7 голосов
/ 26 октября 2011

Используемые вами страницы несколько сбивают вас с толку. Ни ваша «таблица UTF-8», ни «таблица Unicode» не дают вам значения кодовой точки в UTF-8. Они оба просто перечисляют значение Unicode символов.

В Юникоде каждому символу («кодовая точка») присваивается уникальный номер. Символу ö присваивается кодовая точка U+00F6, которая равна F6 в шестнадцатеричном и 246 в десятичном виде.

UTF-8 - это представление Unicode, использующее последовательность от одного до четырех байтов на кодовую точку Unicode. Преобразование из 32-битных кодовых точек Unicode в последовательности байтов UTF-8 описано в этой статье - это довольно просто сделать, как только вы к этому привыкнете. Конечно, компьютеры делают это постоянно, но вы можете легко это сделать карандашом и бумагой, а в голове немного потренироваться.

Если вы выполните это преобразование, вы увидите, что U+00F6 преобразуется в последовательность UTF-8 C3 B6, или 1100 0011 1011 0110 в двоичном формате, поэтому это представление UTF-8 ö.

Другая половина вашего вопроса касается ISO-8859-1. Это кодировка символов, обычно называемая " Latin-1 ". Числовые значения кодировки Latin-1 совпадают с первыми 256 кодовыми точками в Unicode, поэтому ö равно F6 в Latin-1.

После преобразования между UTF-8 и стандартными кодовыми точками Unicode (UTF-32) получить кодировку Latin-1 будет тривиально. Однако не все последовательности UTF-8 / символы Unicode имеют соответствующие символы Latin-1.

См. Отличную статью Абсолютный минимум для каждого разработчика программного обеспечения. Абсолютно, положительно необходимо знать о Unicode и наборах символов (никаких оправданий!) для лучшего понимания кодировок и преобразований между ними.

2 голосов
/ 26 октября 2011
unsigned cha_latin2utf8(unsigned char *dst, unsigned cha)
{
if (cha <  0x80)  { *dst = cha; return 1; }
    /* all 11 bit codepoints (0x0 -- 0x7ff)
      ** fit within a 2byte utf8 char
      ** firstbyte = 110 +xxxxx := 0xc0 + (char>>6) MSB
      ** second    = 10 +xxxxxx := 0x80 + (char& 63) LSB
      */
    *dst++ = 0xc0 | (cha >>6) & 0x1f; /* 2+1+5 bits */
    *dst++ = 0x80 | (cha) & 0x3f; /* 1+1+6 bits */

return 2; /* number of bytes produced */
}

Чтобы проверить это:

#include <stdio.h>
int main (void)
{
char buff[12];

cha_latin2utf8 ( buff, 0xf6);

fprintf(stdout, "%02x %02x\n"
    , (unsigned) buff[0] & 0xff
    , (unsigned) buff[1] & 0xff );

return 0;
}

Результат:

c3 b6
...