Как стать автором
Обновить

Комментарии 37

Зачитался. Хочу продолжения :)
К слову, эта статья есть в книге «Джоэль о программировании». Книга на русском. В ней лучшие подборки статей с блога Джоэля.

Сорри, не туда
Заработался:( пора домой…
Молодец, все туда. Сам хотел комментарий написать про Джоэля Спольски, вот даже ссылку нашел: habrahabr.ru/sandbox/47663/
Если ваш комментарий не саркастичный, то могу похвастаться, что буквально в субботу купил последний экземпляр данной книги(за 2006 год которая) в своем городе:)
Джоэл много чего написал и нарекомендовал, а вот стек оверфлоу больше похож на хорошую бизнес идею, чем на проект с сильной реализацией.

Вот тут можно посмотреть что за 12 лет он понаписал больше тысячи статей www.joelonsoftware.com/backIssues.html

A вот тут посмотреть на стек оверфлоу highscalability.com/blog/2011/3/3/stack-overflow-architecture-update-now-at-95-million-page-vi.html — пара десятков серверов да пяток свичей.

Возможно он говорит правильные вещи, но мне кажется, что они у него больше от философствования, чем от опыта разработки 8)
Stackoverflow — он не в серверах, а в комьюнити. На знаю насчет бизнес идеи, но для програмистов это просто незаменимый ресурс. Если у вас есть вопрос о программировании, вы почти наверняка найдете десяток готовых ответов на этом сайте. При чем качество меня продолжает изумлять —такие подробные и развернутые ответы трудно встретить в другом месте.
Ну вот я примерно об этом и говорю, что создание stackoverflow не подтверждает его сильной квалификации как технаря, но говорит о неплохом бизнес-чутье (в широком понимании слова «бизнес»).
Если ничего не случится, то продолжение будет завтра, максимум послезавтра.
Блин. Не могу передать насколько я Вам благодарен за эту статью. Я ВСЕ ПОНЯЛ! И хотя я и до этого читал статьи про кодировки, хотя сама тема, признаю, достаточно проста, но почему-то до Вашей статьи у меня все равно оставался сумбур в голове.
+∞ Вам в жизненную карму! =)
Статья не моя, я просто сделал перевод. Рад, что он оказался полезен.
У меня была интересная идея сжимать файлы, засовывая внутрь определение его кодировки. Т.е. например в файле в котором используются только кириллица — можно в одном байте ужимать например 2 символа, при этом сначала поставить флаг, означающий кириллицу…
Не выйдет, в 4 бита влезет только 32 комбинации, а в русском алфавите 33 буквы (+33 больших + несколько знаков пунктуации). Но есть более интересные алгоритмы. Вы видели когда-то «Код Хаффмана» (http://ru.wikipedia.org/wiki/Код_Хаффмана)? Принцип работы примерно такой — анализируем текст, наиболее часто встречающийся символ помечаем как 1, второй по популярности как 10, третий 11 и так далее. Очень красиво и лаконично, я считаю.
Только не совсем так. Второй по популярности нельзя обозначить как 10, потому что дешифровщик решит, что единичка принадлежит первому по популярности, а на нолике он споткнётся. Строго говоря, в этом коде самый популярный символ всегда будет кодироваться либо ноликом либо единичкой, а коды для второго и всех последующих всегда будут начинаться с противоположного символа. То есть, если самый популярный имеет код 0, то все остальные будут начинаться с 1, и наоборот.

Допустим, мы имеем сообщение из 7 символов (АББВАБВ), А и В встречаются по 2 раза, Б встречается 3 раза, тогда согласно алгоритму (он есть по вашей ссылке), А и В объединяются в символ АВ с суммой 4, дуге в сторону А присваивается 0, дуге в сторону В присваивается 1, затем новая вершина АВ объединяется с вершиной Б, в сторону Б идёт, допустим, 1 (на самом деле всё равно, 0 или 1), а в сторону вершины АВ идёт 0. Построение дерева закончилось, считываем по дугам коды символов от корневой вершины), так для А получаем АБВ -> АВ -> А = 00, для Б получаем АБВ -> Б = 1, а для В получаем АБВ -> АВ -> В = 01.

Корявая картинка:
image
Спасибо, что поправили. Статья об этом алгоритме на Хабре, если кому интересно habrahabr.ru/post/144200/
ох, сколько оригинал статьи был у меня в закладках. Все вот-вот собирался прочитать. Благодаря вам наконец-то прочту :)
вы не поверите, я читал эту замечательную статью ещё около года назад, а буквально вчера собирался сделать её перевод, но вы меня опередили :)! Спасибо за труд, отлично получилось!
Не понял один момент, почему в 4 строке UTF-8 использует 3 бита? Объясните пожалуйста.
A UTF-8 01000001
A UTF-16 00000000 01000001
A UTF-32 00000000 00000000 00000000 01000001
あ UTF-8 11100011 10000001 10000010
あ UTF-16 00110000 01000010
あ UTF-32 00000000 00000000 00110000 01000010

Я статью не читал, но насколько я понял, ваш вопрос в том, почему в UTF-16 тот же символ занимает два байта. Похоже, дело в том, что в некоторых ситуациях служебная информация в UTF-16 занимает меньше места.

Вот цитата из википедии:
Characters U+0800 through U+FFFF use three bytes in UTF-8, but only two in UTF-16. As a result, text in (for example) Chinese, Japanese or Hindi could take more space in UTF-8 if there are more of these characters than there are ASCII characters. This happens for pure text,[35] but rarely for HTML documents. For example, both the Japanese UTF-8 and the Hindi Unicode articles on Wikipedia take more space in UTF-16 than in UTF-8 .[
В UTF-16 нет служебной информации. Все символы из базовой многоязыковой плоскости будут закодированы 16 битами в UTF-16, и только после U+10000 понадобится 32 бита.

Иными словами, UTF-16 так же относится к UCS-2, как UTF-8 к ASCII, то есть является надмножеством.
А как при декодировании узнать сколько байт занимает следующий символ?
Проанализировав биты первого байта. В случае с UTF-8 длина символа определяется так:

0xxx xxxx — один
110x xxxx — два
1110 xxxx — три

и т.п.

Все непервые байты символов при этом должны будут иметь вид 10xx xxxx, поэтому разрыв потока грозит потерей максимум одного символа.
Да нет, в UTF-8 я понимаю как это происходит — с помощью служебных бит. Но если их нет в UTF-16, как определить символ занимает два или четыре байта?
UTF-16 эксплуатирует тот факт, что с U+D800 по U+DFFF в Юникоде валидных символов быть не может, и использует этот диапазон для четырёхбайтовго кодирования всех дополнительных планов с U+10000 по U+10FFFF. Стало быть, если попадается 1101 01xx — 1101 xxxx, то перед нами четырёхбайтовый символ.
Спасибо. Меня всегда поражало сколько информации в UTF-8 расходуется впустую. Случайно промазал по плюсику, но я вам компенсирую ;-).
Зато экономит много байт, если весь или большая часть текста в ASCII.
Это потому, что бит(ы) указывающие на то, что кодпоинт использует дополнительные байты тоже занимают место.
Потому что в UTF-8 все значения, не влезающие в диапазон от 0 до 127 кодируются следующим образом. В первом байте идёт столько единиц, сколько всего байт используется для кодирования символа, затем идёт ноль, а оставшиеся биты — это уже часть бинарного представления самого числа. Затем идут по 6 бит записи числа, с префиксом 10. Таким образом, в 2 байтах можно записать 11 бит, т.к. в первом байте будет 3 служебных бита, во втором — 2. А этого недостаточно для кодирования 14-битного значения.
Ох, это другая статья, прошу прощения.
Спасибо за отличный перевод. Хотелось бы дополнить.
В вопросе кодировок мне в своё время помогла книга «Dive Into Python 3».
Что касается Python, то
Characters are an abstraction. A string is a sequence of those abstractions.

по русски говоря:
Символы — это абстракция. А строки — это последовательность таких абстракций.

Иными словами, пока вы в Python коде работаете со строками, то совершенно не нужно знать, как эти строки представляются байтами. Со строками можно производить обычные действия: разрезать, менять регистр, делать замены, не задумываясь о каких-то там кодировках. А вот когда вам понадобится сохранить строку в файл или прочитать из сокета, тогда возникнет вопрос: как последовательность символов превратить в набор байт и обратно. Кодировки в Python возникают только при конвертации string <=> bytes.
Это знание помогло мне не беспокоится по пустякам, придало уверенности, мои волосы стали мягкие и шелковистые, и Я стал по другому смотреть на мир.
Да, кстати, мне когда то эти простые правила помогли избавиться от проблем с кодировками. Теперь я даже не понимаю, почему говорят что в 2.х есть какие то проблемы с кодировками. На практике я их не встречаю.
Вот только charset и encoding — нифига не одно и тоже.

charset — набор символов, таблица сопоставления буквам чисел. Например, ascii, windows-1251, unicode.
encoding — в общем случае способ представления чисел битами. Например, 8bit (1 байт на число), utf-8, base64.

Более точные определния даны в стандарте unicode, где-то в началных главах.

То, что в заголовках http и в функциях php они перепутаны, не значит, что это одно и тоже.
Хороший способ оконфузиться в этих терминах: почить man recode.
Ну вот и развилась поддержка юникода до той черты, что можно такую статью читать прямо в браузере, и при этом символы вставлены именно символами, а не картинками.
При решении практических задач, часто возникает необходимость узнать кодировку текста (часто русскоязычного текста). Помочь может универсальный декодировщик (много их разных, я пользуюсь — 2cyr.com/decode/?lang=ru )
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории