Кодирование и декодирование UTF-8,UTF-16?
Господа, помогите понять, некоторые нюансы.
Например у меня есть такая вот строка "6E E282AC21" в hex ее надо декодировать в UTF-8 и узнать символ.
И другой пример в обратную сторону кодировать строку UTF-16 "n€!" в hex.
Вот материал в википедии http://en.wikipedia.org/wiki/UTF-8
Как бы все предельно понятно, но все таки непонятки есть, может кто-то написать в двух словах последовательность действий(кодирование, декодирование)?
Мне это не программировать нужно, а на бумажке решать, так что нужно понять...
Я себе это так представляю, каждую пару преобразовывать в двоичную систему и потом высчитывать, но в табличке в википедии стоит что это может быть и 2 пары, и три.
Например как мне понимать. Это один символ "6E" или это "6EЕ2", или это "6ЕЕ282"?
В первом 8 бит, во втором 16 бит, в 3 24 бита.
Спасибо за советы.
Вопрос 2 - не понял что за пары. В статье про такие "пары" тоже не увидел.
Парой я имел введу - две пары битов. Например "6EE2" - это две пары битов, "6EE228" - это три пары.
Я не понимаю как узнать сколько в этой строке знаков? в табличке той что на википедии показывает, что может быть 1,2,3 и 4 бита..
Понимаете, что я пытаюсь спросить? :(
блииин попутал, должен был написать байты. :)
тоисть к примеру моя последовательность это все очень просто?
"6E E2 82 AC 21" - 5 символов? Или? А можете к примеру указать, что из этого получится? Потому, что если посмотреть в табличке, то 3 символ "8 строка, 2 столбец"?
Тэк... начинаем разребать кашу.
1) Все данные в компе всегда и везде это тупо последовательность бит. Т.е. единица или ноль. Все. Даже байта как атомарной единицы не существует. Это не более, чем исторически сложившийся способ логического объединения бит в группы (а есть такое объединение как машинное слово, в общем много их). Самый ходовой тип байта содержит 8 бит. Поэтому думая о кодировках нужно в первую очередь думать на уровне бит при этом понимая, что логически последовательность из 8 бит это 1 байт.
Это не более чем текстовой способ описания. Но их существуем множество: в двоичном виде, восьмиричном, шестнадцатиричном или вовсе как это принято для юникода через U+ префикс. И с шестнадцатиричной системой порой возникает проблема потому как существует несколько нотаций как делать записи в этой системе. К примеру, в бейсике принято перед таких числом писать префикс &h, в яве и си префикс 0x, есть ассамблеры с префиксом $ и даже с суффиксом h (т.е. в конце числа ставят тупо букву h). В реальности этих префиксов и суффиксов не существует, их нет в последовательности бит строки. Их придумали и ввели для удобства записи и чтения человеком.
В твоем примере можно делать расчеты переводя пару символов в двоичную систему с понимаем того, что это один байт. Но это не означает, что нельзя сделать тоже самое оперируя один символом (который кодирует полбайта, т.е. 4 бита) ли же 3, или все. Все равно в итоге это дает одну и туже двоичную строку. Показываю на примере "6EE282":
посимвольно - 6 это 0110, E это 1110, E это 1110, 2 это 0010, 8 это 1000, 2 это 0010 итого 0110 1110 1110 0010 1000 0010;
по два символа - 6E это 0110 1110, E2 это 1110 0010, 82 это 1000 0010 итого 0110 1110 1110 0010 1000 0010;
по три символа - ... итого 0110 1110 1110 0010 1000 0010.
Поэтому всегда будет одна и таже бинарная строка. После того, как с байтами становиться все понятно, нужно понять идею интерпретации.
Сколько байт занимает один символ это не более чем такая же логическая группировка как и группировка бит в байты. Что бы правильно делать конвертацию, нужно просто понимать сколько байт на символ отводят в той или иной кодовой таблице. К примеру, в utf-8 на символ может отводиться от 1 до 4 байт. Как определить я писал тут http://habrahabr.ru/blogs/erlang/52493/#comment_1396052 . Для utf-16 на символ отводиться от 2 до 4 байт. Определить можно по, цитирую википедию, "Символы с кодами 0x0000..0xD7FF и 0xE000..0xFFFF представляются одним 16-битным словом, а символы с кодами 0x10000—0x10FFFF — в виде последовательности двух 16-битных слов", т.е. нужно взять от начала 2, 3 и 4 байта и посмотреть если ли в юникоде для этих вариантов хоть какие то печатные символы. Исходя из этого узнать размерность символа в байтах в данной конкретной двоичной строке и уже дальше читать блоками посимвольно (поскольку в utf-16, в отличие от utf-8, в пределах одной двоичной строки количество байт приходящихся на один символ постоянно).
На самом деле должно. камрад alekciy не осветил вопрос порядка байтов. Вам придется его изучить так как кодировка UTF-16 может использовать различный порядок байтов.
Я намеренно на стал углубляться в эту тему. Во-первых автор явно указал используемую кодировку - UTF-16. Ну а во-вторых, у человека не устаканился вообще сам концепт, а ты предлагаешь его еще пригрузить порядком байт :D . Акстись!
Полагаю это опечатка и имелась в виду UTF-8? Кодирование UTF-16 какраз зависит от порядка байтов.
Нет не опечатка. Байтовых порядков у нас всего два, значит один из них может считать "дефолтным" и термин UTF-16 легитимным. Если BOM нет, то UTF-16 == UTF-16BE ("What are some of the differences between the UTFs"). В общем в контексте топика это не важно, автор стал бы использовать либо одну, либо другую, вариантов-то всего два и не важно, какой будет выбран как основной. Больше простора для дальнейшей самостоятельной работы.