14 Кодирование символов ответы к тесту – Тарифы на сотовую связь
410 пользователя считают данную страницу полезной.
Информация актуальна! Страница была обновлена 16.12.2019
2. Сколько различных символов можно использовать при 4-битном коде (на каждый символ отводится 4 бит)?
3. При перекодировке сообщения на русском языке из 16-битного кода UNICODE в 8-битную кодировку KOI8-R оно уменьшилось на 560 битов. Какова длина сообщения в символах?
4. При перекодировке сообщения из 8-битного кода в 16-битную кодировку UNICODE его объём увеличился на 1024 байта. Каков был информационный объём сообщения (в байтах) до перекодировки?
5. Текст, содержащий 80 страниц (на каждой странице 32 строки по 50 символов в каждой) закодирован в 8-битной кодировке. Определите информационный объем текста в Кбайтах.
Правильный ответ – после каждого вопроса выделен подчёркнутым курсивом
1. Сколько битов потребуется, чтобы размесить в памяти компьютера фразу «Тили-тили тесто!»?
Правильный ответ: b)
2. Максимальное значение энтропии источника, который порождает 16 различных символов равно:
c) нельзя определить
3. Коэффициент сжатия для источника с вероятностями , , , равен:
Правильный ответ: a)
4. Энтропия Шеннона обладает свойством:
Правильный ответ: a)
5. Количество информации, содержащееся в двух статистически зависимых сообщениях, оценивается величиной:
a) энтропии Шеннона
b) условной энтропии
c) относительной энтропии
Правильный ответ: b)
1. Является ли побуквенный код , , для источника префиксным?
c) нельзя определить
Правильный ответ: b)
2. Является ли побуквенный код , , для источника разделимым?
c) нельзя определить
Правильный ответ: b)
3. Является ли побуквенный код , , однозначно декодируемым?
c) нельзя определить
Правильный ответ: a)
4. Выполняется ли неравенство Крафта для кода , , ?
Правильный ответ: a)
тест 5. После кодирования сообщения побуквенным кодом , , получена последовательность 001001100. Исходное сообщение имело вид:
a)
b)
c)
Правильный ответ: a)
1. Средняя длина кодового слова побуквенного кода , , , для источника с равномерным распределением вероятностей равна:
Правильный ответ a)
2. Избыточность побуквенного кода , , , для источника с равномерным распределением вероятностей равна:
Правильный ответ b)
3. Является ли код , , , для источника с равномерным распределением вероятностей оптимальным?
Правильный ответ b)
4. Является ли код , , , для источника с распределением вероятностей ,, , оптимальным?
Правильный ответ a)
5. Средняя длина кодового слова кода , , , для источника с распределением вероятностей ,, , равна:
Правильный ответ a)
1 тест. Для кода Шеннона справедливо соотношение:
a)
b)
c)
Правильный ответ b)
2. Длина кодового слова кода Шеннона для символа определяется из соотношения ( – вероятность появления символа ):
a)
b)
c)
Правильный ответ a)
3. Средняя длина кодового слова кода Фано для источника с равномерным распределением вероятностей равна:
Правильный ответ a)
4. Совпадают ли коды Фано и Хаффмана для источника с равномерным распределением вероятностей?
c) возможны обе ситуации
Правильный ответ с)
5 тест. Совпадают ли средние длины кодов Фано и Хаффмана для источника с равномерным распределением вероятностей?
Правильный ответ a)
1. Адаптивные методы кодирования применяются для кодирования сообщений, которые порождают источники:
a) с известной статистикой
b) с неизвестной статистикой
c) с равномерным распределением вероятностей
Правильный ответ b)
2. Для оценки статистики источника сообщений используется:
a) скользящее окно
b) подвижное окно
c) пластиковое окно
Правильный ответ а)
3. Адаптивный код Хаффмана был предложен:
Правильный ответ b)
4. Адаптивный код «стопка книг» позволяет хорошо сжимать сообщения:
a) с равномерным распределением символов
b) с большим количеством одинаковых символов
c) одинаково хорошо сжимает любые сообщения
Правильный ответ а)
тест№ 5. Необходимо ли при кодировании сообщения кодом «стопка книг» знать вероятностное распределение символов источника?
Правильный ответ а)
1. Словарные методы кодирования применяются для кодирования сообщений, которые порождают источники:
a) с известной статистикой
b) с неизвестной статистикой и меняющейся статистикой
c) с равномерным распределением вероятностей
Правильный ответ b)
2. Основными видами словарных методов типа LZ являются:
a) адаптивные коды и оптимальные коды
b) коды со скользящим окном и коды с использованием адаптивного словаря
c) адаптивный код Хаффмана и коды с использованием адаптивного словаря
Правильный ответ b)
3. При словарном кодировании адаптивный словарь используется:
a) для хранения ранее встречавшихся комбинаций символов и их кодов
Содержание урока:
14.1. Кодировка ASCII и её расширения | ||
Кодирование текстовой информации | 14.2. Стандарт Unicode |
14.1. Кодировка ASCII и её расширения
Основой для компьютерных стандартов кодирования символов послужил код ASCII (American Standard Code for Information Interchange) — американский стандартный код для обмена информацией, разработанный в 1960-х годах в США и применявшийся для любых, в том числе и некомпьютерных, способов передачи информации (телеграф, факсимильная связь и т. д.). Этот код 7-битовый: общее количество символов составляет 2 7 = 128, из них первые 32 символа — управляющие, а остальные — изображаемые, т. е. имеющие графическое изображение. К изображаемым символам в ASCII относятся буквы латинского алфавита (прописные и строчные), цифры, знаки препинания и арифметических операций, скобки и некоторые специальные символы. Кодировка ASCII приведена в табл. 3.8.
Таблица 3.8
Кодировка ASCII
Хотя для кодирования символов в ASCII достаточно 7 битов, в памяти компьютера под каждый символ отводится ровно 1 байт (8 битов), при этом код символа помещается в младшие биты, а в старший бит заносится 0.
Например, 01000001 — код прописной латинской буквы «А»; с помощью шестнадцатеричных цифр его можно записать как 41.
Стандарт ASCII рассчитан на передачу только английского текста. Со временем возникла необходимость кодирования и неанглийских букв. Во многих странах для этого стали разрабатывать расширения ASCII -кодировки, в которых применялись однобайтовые коды символов. При этом первые 128 символов кодовой таблицы совпадали с кодировкой ASCII, а остальные (со 128-го по 255-й) использовались для кодирования букв национального алфавита, символов национальной валюты и т. п. Из-за несогласованности этих разработок для многих языков было создано несколько вариантов кодовых таблиц (например, для русского языка их было создано около десятка!).
Впоследствии использование кодовых таблиц было несколько упорядочено: каждой кодовой таблице было присвоено особое название и номер. Для русского языка наиболее распространёнными стали однобайтовые кодовые таблицы CP-866, Windows-1251 (табл. 3.9) и КОИ-8 (табл. 3.10). В них первые 128 символов совпадают с ASCII-кодировкой, а русские буквы размещены во второй части таблицы. Обратите внимание на то, что коды русских букв в этих кодировках различны.
Таблица 3.9
Кодировка Windows-1251
Таблица 3.10
Кодировка КОИ-8
Мы выяснили, что при нажатии на алфавитно-цифровую клавишу в компьютер посылается некоторая цепочка нулей и единиц. В текстовых файлах хранятся не изображения символов, а их коды.
При выводе текста на экран монитора или принтера необходимо восстановить изображения всех символов, составляющих данный текст, причём изображения эти могут быть разнообразны и достаточно причудливы. Внешний вид выводимых на экран символов кодируется и хранится в специальных шрифтовых файлах. Современные текстовые процессоры умеют внедрять шрифты в файл. В этом случае файл содержит не только коды символов, но и описание используемых в этом документе шрифтов. Кроме того, файлы, создаваемые с помощью текстовых процессоров, включают в себя и такие данные о форматировании текста, как его размер, начертание, размеры полей, отступов, межстрочных интервалов и другую дополнительную информацию.
Cкачать материалы урока
Кодирование текста — презентация онлайн
Задание №1Кодирование текста
Никифоров Николай Сергеевич
МБОУ СОШ №26 г. Сургут
http://online.fiinno.ru
[email protected]
№1 (Демоверсия ФИПИ – 2020)
В одной из кодировок Unicode каждый символ кодируется 16 битами.
Вова написал текст (в нём нет лишних пробелов):
«Ёж, лев, слон, олень, тюлень, носорог, крокодил, аллигатор – дикие животные».
Ученик вычеркнул из списка название одного из животных. Заодно он вычеркнул
ставшие лишними запятые и пробелы – два пробела не должны идти подряд.
При этом размер нового предложения в данной кодировке оказался на 16 байт
меньше, чем размер исходного предложения. Напишите в ответе вычеркнутое
название животного.
Решение:
1. По условию: 1 символ – 16 бит = 2 байта (1 байт = 8 бит).
2. Размер нового предложения на 16 байт меньше, чем размер исходного
предложения.
3. 16/2 = 8 (символов) – было вычеркнуто (удалено из текста).
4. Важно! При удалении слова нужно удалить один пробел и лишнюю запятую.
5. 8 символов – 2 символа = 6 символов (содержит вычеркнутое слово).
№2 (СтатГрад – октябрь 2019)
В одной из кодировок Unicode каждый символ кодируется 16 битами.
Вова написал текст (в нём нет лишних пробелов):
«Чиж, грач, стриж, гагара, пингвин, ласточка, жаворонок, свиристель,
буревестник, вертиголовка – птицы».
Ученик вычеркнул из списка название одной птицы. Заодно он вычеркнул
ставшие лишними запятые и пробелы – два пробела не должны идти подряд.
При этом размер нового предложения в данной кодировке оказался на 18 байт
меньше, чем размер исходного предложения. Напишите в ответе вычеркнутое
название птицы.
Решение:
1. По условию: 1 символ – 16 бит = 2 байта (1 байт = 8 бит).
2. Размер нового предложения на 18 байт меньше, чем размер исходного
предложения.
3. 18/2 = 9 (символов) – было вычеркнуто (удалено из текста).
4. Важно! При удалении слова нужно удалить один пробел и лишнюю запятую.
5. 9 символов – 2 символа = 7 символов (содержит вычеркнутое слово).
Ответ: пингвин
№3 (СтатГрад – октябрь 2019)
В одной из кодировок Unicode каждый символ кодируется 16 битами.
Вова написал текст (в нём нет лишних пробелов):
«Чиж, грач, стриж, гагара, пингвин, ласточка, жаворонок, свиристель,
буревестник, вертиголовка – птицы».
Ученик вычеркнул из списка название одной птицы. Заодно он вычеркнул
ставшие лишними запятые и пробелы – два пробела не должны идти подряд.
При этом размер нового предложения в данной кодировке оказался на 12 байт
меньше, чем размер исходного предложения. Напишите в ответе вычеркнутое
название птицы.
Решение:
1. По условию: 1 символ – 16 бит = 2 байта (1 байт = 8 бит).
2. Размер нового предложения на 12 байт меньше, чем размер исходного
предложения.
3. 12/2 = 6 (символов) – было вычеркнуто (удалено из текста).
4. Важно! При удалении слова нужно удалить один пробел и лишнюю запятую.
5. 6 символов – 2 символа = 4 символа (содержит вычеркнутое слово).
Ответ: грач
№4 (А.Г. Минак, вариант №3)
В одной из кодировок Unicode каждый символ кодируется 2 байтами. Иван
написал текст
(в нем нет лишних пробелов):
«Январь, февраль, март, апрель, май, июнь, июль, август, сентябрь, октябрь,
ноябрь, декабрь – месяцы года».
Ученик вычеркнул из списка название одного месяца. Заодно он вычеркнул
ставшие лишними запятые и пробелы – два пробела не должны идти подряд. При
этом размер нового предложения в данной кодировке оказался на 128 бит
меньше, чем размер исходного предложения. Среди месяцев, имеющих
одинаковое количество букв, Иван вычеркивает последний по порядку. Напишите
Решение:
в ответе вычеркнутое название месяца.
1. По условию: 1 символ – 2 байта = 16 бит (1 байт = 8 бит).
2. Размер нового предложения на 128 бит меньше, чем размер исходного
предложения.
3. 128/16 = 8 (символов) – было вычеркнуто (удалено из текста).
4. Важно! При удалении слова нужно удалить один пробел и лишнюю запятую.
5. 8 символов – 2 символа = 6 символов (содержит вычеркнутое слово).
6. По условию: среди месяцев, имеющих одинаковое количество букв, Иван
вычеркивает последний по порядку
№5
В кодировке КОИ-8 каждый символ кодируется 8 битами.
Витя написал текст (в нём нет лишних пробелов):
«Футбол, волейбол, регби, гандбол, теннис, бейсбол, гольф – спортивные игры с
мячом».
Ученик решил добавить в список названий ещё одной игры с мячом — баскетбол.
При этом он добавил в текст необходимую запятую и пробел.
На сколько байт при этом увеличился размер нового предложения в данной
кодировке?
В ответе укажите только одно числоРешение:
— количество байт.
По условию: 1 символ – 8 бит = 1 байт (1 байт = 8 бит).
Добавленное слово: баскетбол содержит 9 символов.
Важно! При добавлении слова нужно добавить один пробел и одну запятую.
9 символов + 2 символа = 11 символов (содержит добавленное слово,
запятая и пробел).
5. 11 символов * 1 байт = 11 байт
1.
2.
3.
4.
Ответ: 11
№6
Статья, набранная на компьютере, содержит 32 страницы текста, на каждой
странице 32 строки, в каждой строке 26 символов. Определите
информационный объём статьи в Кбайтах в одной из кодировок Unicode, в
которой каждый символ кодируется 16 битами.
Решение:
1. Объем информации в тексте: I = K * i,
где K – количество символов, i – информационный объем одного символа в
битах.
K = количество страниц * количество строк * количество символов в строке.
2. I = 32*32*26*16 = 25 * 25 * 21 * 13 * 24 бит = 215 * 13 бит.
1 байт = 8 бит = 23 бит
1 Кбайт = 1024 байт = 210 байт
1 Кбайт = 213 бит
3. Переводим из бит в Кбайты: бит = 22 * 13 Кбайт= 4*13 Кбайт= 52 Кбайт
Ответ: 52
№7
В одной из кодировок Unicode каждый символ кодируется 16 битами.
Определите размер в байтах следующего предложения в данной кодировке:
Кто владеет информацией, тот владеет миром.
Решение:
1. Объем информации в тексте: I = K * i, где K – количество символов, i –
информационный объем одного символа в битах.
2. Количество символов: 43 (включая пробелы и знаки препинания). (Если в
тексте встречается «тире», то выделяется пробелами с двух сторон, а «дефис»
— нет).
3. По условию: 1 символ – 16 бит = 2 байта (1 байт = 8 бит).
4. 43 * 2 = 86 байт.
Ответ: 86
№8
В кодировке UTF-8 каждый символ русского алфавита кодируется 16 битами.
Определите количество символов в сообщении, если информационный объём
сообщения в этой кодировке равен 60 байт.
Решение:
1. Объем информации в тексте: I = K * i, где K – количество символов, i –
информационный объем одного символа в битах.
2. По условию: 1 символ – 16 бит = 2 байта (1 байт = 8 бит).
3. K = = 30 символов
Ответ: 30
№9 (СтатГрад – ноябрь 2019)
Статья, набранная на компьютере, содержит 20 страниц, на каждой странице 40
строк, в каждой строке 48 символов. В одном из представлений Unicode каждый
символ кодируется двумя байтами. Определите информационный объём статьи в
Кбайтах в этом варианте представления Unicode.
Решение:
1. Объем информации в тексте: I = K * i,
где K – количество символов, i – информационный объем одного символа в
битах.
K = количество страниц * количество строк * количество символов в строке.
2. I = 20*40*48*16 = 5*22 *5*23 *3*24 *24 бит = 213 * 75 бит.
1 байт = 8 бит = 23 бит
1 Кбайт = 1024 байт = 210 байт
1 Кбайт = 213 бит
3. Переводим из бит в Кбайты: бит = 75 Кбайт
Ответ: 75
№10 (СтатГрад – ноябрь 2019)
Статья, набранная на компьютере, содержит 10 страниц, на каждой странице 32
строки, в каждой строке 48 символов. В одном из представлений Unicode каждый
символ кодируется 16 битами. Определите информационный объём статьи в
Кбайтах в этом варианте представления Unicode.
Решение:
1. Объем информации в тексте: I = K * i,
где K – количество символов, i – информационный объем одного символа в
битах.
K = количество страниц * количество строк * количество символов в строке.
2. I = 10*32*48*16 = 5*21 *25 *3*24 *24 бит = 214 * 15 бит.
1 байт = 8 бит = 23 бит
1 Кбайт = 1024 байт = 210 байт
1 Кбайт = 213 бит
3. Переводим из бит в Кбайты: бит = 30 Кбайт
Ответ: 30
Кодирование символов : кодовая страница, ASCII
Кодировка символов (часто называемая также кодовой страницей) – это набор числовых значений, которые ставятся в соответствие группе алфавитно-цифровых символов, знаков пунктуации и специальных символов.
Для кодировки символов в Windows используется таблица ASCII (American Standard Code for Interchange of Information).
В ASCII первые 128 символов всех кодовых страниц состоят из базовой таблицы символов. Первые 32 кода базовой таблицы, начиная с нулевого, размещают управляющие коды.
Символ | Код | Клавиши | Значение |
nul | 0 | Ctrl + @ | Нуль |
soh | 1 | Ctrl + A | Начало заголовка |
stx | 2 | Ctrl + B | Начало текста |
etx | 3 | Ctrl + C | Конец текста |
eot | 4 | Ctrl + D | Конец передачи |
enq | 5 | Ctrl + E | Запрос |
ack | 6 | Ctrl + F | Подтверждение |
bel | 7 | Ctrl + G | Сигнал (звонок) |
bs | 8 | Ctrl + H | Забой (шаг назад) |
ht | 9 | Ctrl + I | Горизонтальная табуляция |
lf | 10 | Ctrl + J | Перевод строки |
vt | 11 | Ctrl + K | Вертикальная табуляция |
ff | 12 | Ctrl + L | Новая страница |
cr | 13 | Ctrl + M | Возврат каретки |
so | 14 | Ctrl + N | Выключить сдвиг |
si | 15 | Ctrl + O | Включить сдвиг |
dle | 16 | Ctrl + P | Ключ связи данных |
dc1 | 17 | Ctrl + Q | Управление устройством 1 |
dc2 | 18 | Ctrl + R | Управление устройством 2 |
dc3 | 19 | Ctrl + S | Управление устройством 3 |
dc4 | 20 | Ctrl + T | Управление устройством 4 |
nak | 21 | Ctrl + U | Отрицательное подтверждение |
syn | 22 | Ctrl + V | Синхронизация |
etb | 23 | Ctrl + W | Конец передаваемого блока |
can | 24 | Ctrl + X | Отказ |
em | 25 | Ctrl + Y | Конец среды |
sub | 26 | Ctrl + Z | Замена |
esc | 27 | Ctrl + [ | Ключ |
fs | 28 | Ctrl + \ | Разделитель файлов |
gs | 29 | Ctrl + ] | Разделитель группы |
rs | 30 | Ctrl + ^ | Разделитель записей |
us | 31 | Ctrl + _ | Разделитель модулей |
Базовая таблица кодировки ASCII
32 пробел | 48 0 | 64 @ | 80 P | 96 ` | 112 p |
33 ! | 49 1 | 65 A | 81 Q | 97 a | 113 q |
34 “ | 50 2 | 66 B | 82 R | 98 b | 114 r |
35 # | 51 3 | 67 C | 83 S | 99 c | 115 s |
36 $ | 52 4 | 68 D | 84 T | 100 d | 116 t |
37 % | 53 5 | 69 E | 85 U | 101 e | 117 u |
38 & | 54 6 | 70 F | 86 V | 102 f | 118 v |
39 ‘ | 55 7 | 71 G | 87 W | 103 g | 119 w |
40 ( | 56 8 | 72 H | 88 X | 104 h | 120 x |
41 ) | 57 9 | 73 I | 89 Y | 105 i | 121 y |
42 * | 58 : | 74 J | 90 Z | 106 j | 122 z |
43 + | 59 ; | 75 K | 91 [ | 107 k | 123 { |
44 , | 60 < | 76 L | 92 \ | 108 l | 124 | |
45 — | 61 = | 77 M | 93 ] | 109 m | 125 } |
46 . | 110 n | 126 ~ | |||
47 / | 63 ? | 79 O | 95 _ | 111 o | 127 |
Символы с номерами от 128 до 255 представляют собой таблицу расширения и варьируются в зависимости от набора скриптов, представленных кодировкой символов. Набор символов таблицы расширения различается в зависимости от выбранной кодовой страницы:
1251 – кодовая страница Windows
128 Ђ | 144 Ђ | 160 | 176 ° | 192 А | 208 Р | 224 а | 240 р |
129 Ѓ | 145 ‘ | 161 Ў | 177 ± | 193 Б | 209 С | 225 б | 241 с |
130 ‚ | 146 ’ | 162 ў | 178 I | 194 В | 210 Т | 226 в | 242 т |
131 ѓ | 147 “ | 163 J | 179 i | 195 Г | 211 У | 227 г | 243 у |
132 „ | 148 ” | 164 ¤ | 180 ґ | 196 Д | 212 Ф | 228 д | 244 ф |
133 … | 149 • | 165 Ґ | 181 μ | 197 Е | 213 Х | 229 е | 245 х |
134 † | 150 – | 166 ¦ | 182 ¶ | 198 Ж | 214 Ц | 230 ж | 246 ц |
135 ‡ | 151 — | 167 § | 183 · | 199 З | 215 Ч | 231 з | 247 ч |
136 € | 152 □ | 168 Ё | 184 ё | 200 И | 216 Ш | 232 и | 248 ш |
137 ‰ | 153 ™ | 169 © | 185 № | 201 Й | 217 Щ | 233 й | 249 щ |
138 Љ | 154 љ | 170 Є | 186 є | 202 К | 218 Ъ | 234 к | 250 ъ |
139 < | 155 > | 171 « | 187 » | 203 Л | 219 Ы | 235 л | 251 ы |
140 Њ | 156 њ | 172 ¬ | 188 j | 204 М | 220 Ь | 236 м | 252 ь |
141 Ќ | 157 ќ | 173 | 189 S | 205 Н | 221 Э | 237 н | 253 э |
142 Ћ | 158 ћ | 174 ® | 190 s | 206 О | 222 Ю | 238 о | 254 ю |
143 Џ | 159 џ | 175 Ï | 191 ї | 207 П | 223 Я | 239 п | 255 я |
866 – кодовая страница DOS
128 А | 144 Р | 160 а | 176 ░ | 192 └ | 208 ╨ | 224 р | 240 ≡Ё |
129 Б | 145 С | 161 б | 177 ▒ | 193 ┴ | 209 ╤ | 225 с | 241 ±ё |
130 В | 146 Т | 162 в | 178 ▓ | 194 ┬ | 210 ╥ | 226 т | 242 ≥ |
131 Г | 147 У | 163 г | 179 │ | 195 ├ | 211 ╙ | 227 у | 243 ≤ |
132 Д | 148 Ф | 164 д | 180 ┤ | 196 ─ | 212 ╘ | 228 ф | 244 ⌠ |
133 Е | 149 Х | 165 е | 181 ╡ | 197 ┼ | 213 ╒ | 229 х | 245 ⌡ |
134 Ж | 150 Ц | 166 ж | 182 ╢ | 198 ╞ | 214 ╓ | 230 ц | 246 ¸ |
135 З | 151 Ч | 167 з | 183 ╖ | 199 ╟ | 215 ╫ | 231 ч | 247 » |
136 И | 152 Ш | 168 и | 184 ╕ | 200 ╚ | 216 ╪ | 232 ш | 248 ° |
137 Й | 153 Щ | 169 й | 185 ╣ | 201 ╔ | 217 ┘ | 233 щ | 249 · |
138 К | 154 Ъ | 170 к | 186 ║ | 202 ╩ | 218 ┌ | 234 ъ | 250 ∙ |
139 Л | 155 Ы | 171 л | 187 ╗ | 203 ╦ | 219 █ | 235 ы | 251 √ |
140 М | 156 Ь | 172 м | 188 ╝ | 204 ╠ | 220 ▄ | 236 ь | 252 ⁿ |
141 Н | 157 Э | 173 н | 189 ╜ | 205 ═ | 221 ▌ | 237 э | 253 ² |
142 О | 158 Ю | 174 о | 190 ╛ | 206 ╬ | 222 ▐ | 238 ю | 254 ■ |
143 П | 159 Я | 175 п | 191 ┐ | 207 ╧ | 223 ▀ | 239 я | 255 |
Русские названия основных спецсимволов:
Символ | Название |
` | гравис, кавычка, обратный машинописный апостроф |
` | гравис, кавычка, обратный машинописный апостроф |
~ | тильда |
! | восклицательный знак |
@ | эт, коммерческое эт, «собака» |
# | октоторп, решетка, диез |
$ | знак доллара |
% | процент |
^ | циркумфлекс, знак вставки |
& | амперсанд |
* | астериск, звездочка, знак умножения |
( | левая открывающая круглая скобка |
) | правая закрывающая круглая скобка |
— | минус, дефис |
_ | знак подчеркивания |
= | знак равенства |
+ | плюс |
[ | левая открывающая квадратная скобка |
] | правая закрывающая квадратная скобка |
{ | левая открывающая фигурная скобка |
} | правая закрывающая фигурная скобка |
; | точка с запятой |
: | двоеточие |
‘ | машинописный апостроф, одинарная кавычка |
« | двойная кавычка |
, | запятая |
. | точка |
/ | слэш, косая черта, знак дроби |
< | левая открытая угловая скобка, знак меньше |
> | правая закрытая угловая скобка, знак больше |
\ | обратный слэш, обратная косая черта |
| | вертикальная черта |
Кодировка UNICODE
Юникод (Unicode) — стандарт кодирования символов, позволяющий представить знаки практически всех письменных языков. Стандарт предложен в 1991 году некоммерческой организацией «Консорциум Юникода».
В Unicode используются 16-битовые (2-байтовые) коды, что позволяет представить 65536 символов.
Применение стандарта Unicode позволяет закодировать очень большое число символов из разных письменностей: в документах Unicode могут соседствовать китайские иероглифы, математические символы, буквы греческого алфавита, латиницы и кириллицы, при этом становится ненужным переключение кодовых страниц.
Для представления символьных данных в кодировке Unicode используется символьный тип wchar_t.
ASCII | UNICODE |
char | wchar_t |
1 байт | 2 байта |
Тип кодировки задается в свойствах проекта Microsoft Visual Studio:
Многобайтовая кодировка предполагает использование кодировки ASCII.
При этом при построении проекта используется директива условной компиляции, переопределяющая тип TCHAR:
#ifdef _UNICODE
typedef wchar_t TCHAR;
#else
typedef char TCHAR;
#endif
Для перекодирования строки в формат Unicode без изменения кодировки файла используется макроопределение
_T(«строка»)
Прототип макроса содержится в файле tchar.h.
Назад: Представление данных и архитектура ЭВМ
Использование UTF-8 в HTTP заголовках – CUBA Platform
Как известно, HTTP 1.1 — это текстовой протокол передачи данных. HTTP сообщения закодированы, используя ISO-8859-1 (которую условно можно считать расширенной версией ASCII, содержащей умляуты, диакритику и другие символы, используемые в западноевропейских языках). При этом в теле сообщений можно использовать другую кодировку, которая должна быть обозначена в заголовке «Content-Type». Но что делать, если нам необходимо задать non-ASCII символы не в теле сообщения, а в самих заголовках? Наверное, самый распространенный кейс — это проставление имени файла в «Content-Disposition» заголовке. Это, казалось бы, довольно распространенная задача, но ее реализация не так очевидна.
TL;DR: Используйте кодировку, описанную в RFC 6266, для «Content-Disposition» и преобразуйте текст в латиницу (транслит) в остальных случаях.
Небольшая вводная в кодировки
В статье упоминаются и используются кодировки US-ASCII (часто именуемую просто ASCII), ISO-8859-1 и UTF-8. Это небольшая вводная в эти кодировки. Раздел предназначен для разработчиков, которые редко или совсем не работают с кодировками и успели подзабыть их. Если вы к ним не относитесь, то смело пропускайте раздел.
ASCII — это простая кодировка, содержащая 128 символов и включающая весь английский алфавит, цифры, знаки препинания и служебные символы.8 = 256 вариантов.
ISO-8859-1 — кодировка, предназначенная для западноевропейских языков. Содержит французскую диакритику, немецкие умляуты и т.д.
Кодировка содержит 256 символов и, таким образом, может быть представлена одним байтом. Первая половина (128 символов) полностью совпадает с ASCII. Таким образом, если первый бит = 0, то это обычный ASCII символ. Если 1, то это символ, специфичный для ISO-8859-1.
UTF-8 — одна из самых известных кодировок наравне с ASCII. Способна кодировать 1.112.064 символов. Размер каждого символа варьируется от 1-го до 4-х байт (раньше допускались значения до 6 байт).
Программа, работающая с этой кодировкой, определяет по первым битам, как много байтов входит в символ. Если октет начинается с 0, то символ представлен одним байтом. 110 — два байта, 1110 — три байта, 11110 — 4 байта.
Как и в случае с ISO-8859-1, первые 128 символов полностью соответствуют ASCII. Поэтому тексты, использующие только ASCII символы, будут абсолютно идентичны в бинарном представлении, вне зависимости от того, использовалась ли для кодирования US-ASCII, ISO-8859-1 или UTF-8.
Использование UTF-8 в теле сообщения
Прежде чем перейти к заголовкам, давайте быстро взглянем, как использовать UTF-8 в теле сообщений. Для этого используется заголовок «Content-Type».
Если «Content-Type» не задан, то браузер должен обрабатывать сообщения, как будто они написаны в ISO-8859-1. Браузер не должен пытаться отгадать кодировку и, тем более, игнорировать «Content-Type». Но, что реально отобразится в ситуации, когда «Content-Type» не передан, зависит от реализации браузера. Например, Firefox сделает согласно спецификации и прочитает сообщение, будто оно было закодировано в ISO-8859-1. Google Chrome, напротив, будет использовать кодировку операционной системы, которая для многих российских пользователей равна Windows-1251. В любом случае, если сообщение было в UTF-8, то оно будет отображено некорректно.
Проставляем UTF-8 сообщение в значение заголовка
С телом сообщения все достаточно просто. Тело сообщения всегда следует после заголовков, поэтому здесь не возникает технических проблем. Но как быть с заголовками? В спецификации недвусмысленно заявляется, что порядок заголовков в сообщении не имеет значения. Т.е. задать кодировку в одном заголовке через другой заголовок не представляется возможным.
Что будет, если просто взять и записать UTF-8 значение в значение заголовка? Мы видели, что такой трюк с телом сообщения приведет к тому, что значение будет просто прочитано в ISO-8859-1. Логично было бы предположить, что то же самое произойдет с заголовком. Но это не так. Фактически, во многих, если не в большинстве, случаях такое решение будет работать. Сюда включаются старые айфончики, IE11, Firefox, Google Chrome. Единственным из находящихся у меня под рукой браузеров, когда я писал эту статью, который не захотел работать с таким заголовком, является Edge.
Такое поведение не зафиксировано в спецификациях. Возможно, разработчики браузеров решили облегчить жизнь разработчиков и автоматически определять, что в заголовках сообщение закодировано в UTF-8. В общем-то, это не является такой сложной задачей. Смотрим на первый бит: если 0, то ASCII, если 1 — то, возможно, UTF-8.
Нет ли в этом случае пересечения с ISO-8859-1? На самом деле, практически нет. Возьмем для примера UTF-8 символ из 2-х октетов (русские буквы представлены двумя октетами). Символ в бинарном представлии будет иметь вид: 110xxxxx 10xxxxxx. В HEX представлении: [0xC0-0x6F] [0x80-0xBF]. В ISO-8859-1 этими символами едва ли можно закодировать что-то, несущее смысловую нагрузку. Поэтому риск того, что браузер неправильно расшифрует сообщение, очень мал.
Однако, при попытке использовать этот способ можно столкнуться с техническими проблемами: ваш веб-сервер или фреймворк может просто не разрешить записывать UTF-8 символы в значение заголовка. Например, Apache Tomcat вместо всех UTF-8 символов проставляет 0x3F (вопросительный знак). Разумеется, это ограничение можно обойти, но, если само приложение бьет по рукам и не дает что-то сделать, то, возможно, вам и не нужно это делать.
Но, независимо от того, разрешает ли вам ваш фреймворк или сервер записать UTF-8 сообщения в заголовок или нет, я не рекомендую этого делать. Это не задокументированное решение, которое в любой момент времени может перестать работать в браузерах.
Транслит
Я думаю, что использовать транслит — eto bolee horoshee reshenie. Многие крупные популярные русские ресурсы не брезгуют использовать транслит в названиях файлов. Это гарантированное решение, которое не сломается с выпуском новых браузеров и которое не надо тестировать отдельно на каждой платформе. Хотя, разумеется, надо подумать, как преобразовывать весь спектр возможных символов, что может быть не совсем тривиально. Например, если приложение рассчитано на российскую аудиторию, то в имя файла могут попасть татарские буквы ә и ң, которые надо как-то обработать, а не просто заменять на «?».
RFC 2047
Как я уже упомянул, томкат не позволил мне проставить UTF-8 в заголовке сообщения. Отражена ли эта особенность поведения в Java docs для сервлетов? Да, отражена:
Упоминается RFC 2047. Я пробовал кодировать сообщения, используя этот формат, — браузер меня не понял. Этот метод кодировки не работает в HTTP. Хотя работал раньше. Вот, например, тикет на удаление поддержки этой кодировки из Firefox.
RFC 6266
В тикете, ссылка на который содержится в предыдущем разделе, есть упоминания, что даже после прекращения поддержки RFC 2047, все еще есть способ передавать UTF-8 значения в названии скачиваемых файлов: RFC 6266. На мой взгляд, это самое правильно решение на сегодняшний день. Многие популярные интернет ресурсы используют его. Мы в CUBA Platform также используем именно этот RFC для генерации «Content-Disposition».
RFC 6266 — это спецификация, описывающая использование “Content-Disposition” заголовка. Сам способ кодировки подробно описан в другой спецификации — RFC 8187.
Параметр “filename” содержит название файла в ASCII, “filename*” — в любой необходимой кодировке. При наличии обоих атрибутов “filename” игнорируется во всех современных браузерах (включая IE11 и старые версии Safari). Совсем старые браузеры, напротив, игнорируют “filename*”.
При использовании данного способа кодирования в параметре сначала указывается кодировка, после » идет закодированное значение. Видимые символы из ASCII кодирования не требуют. Остальные символы просто пишутся в hex представлении, со стоящим «%» перед каждым октетом.
Что делать с другими заголовками?
Кодирование, описанное в RFC 8187, не является универсальным. Да, можно поместить в заголовок параметр с * префиксом, и это, возможно, будет даже работать для некоторых браузеров, но спецификация предписывает не делать так.
В каждом случае, где в заголовках поддерживается UTF-8, на настоящий момент есть явное упоминание об этом в релевантном RFC. Помимо «Content-Disposition» данная кодировка используется, например, в Web Linking и Digest Access Authentication.
Следует учесть, что стандарты в этой области постоянно меняются. Использование описанной выше кодировки в HTTP было предложено лишь в 2010. Использование данной кодировки именно в «Content-Disposition» было зафиксировано в стандарте в 2011. Несмотря на то, что эти стандарты находятся лишь на стадии «Proposed Standard», они поддержаны повсеместно. Вариант, что в будущем нас ожидают новые стандарты, которые позволят более унифицировано работать с различными кодировками в заголовках, не исключен. Поэтому остается только следить за новостями в мире стандартов HTTP и уровня их поддержки на стороне браузеров.
2. Кодирование текста
Текст в памяти компьютера представляется в виде набора отдельных символов. В качестве таковых рассматриваются не только печатные символы, но и управляющие (переход на следующую строку, маркеры начала и конца файла и др.).
Каждый символ кодируется собственным целым числом, которое хранится в двоичной системе счисления. Назначение такого числа символу определяется соответствующим стандартом. В России традиционно используется несколько таких стандартов.
ASCII
Согласно этому стандарту символ кодируется однобайтовым числом. Соотношение числа и символа берется из предварительно сформированной таблицы, в которой каждому символу соответствует только одно число. Всего можно закодировать только 256 символов. Такое число не позволяет использовать одновременно все национальные алфавиты мира, поэтому разработчики предусмотрели разделение всей таблицы на части:
0..31 — специальные, управляющие символы;
32..126 — часто использующиеся символы: латиница, цифры, знаки пунктуации и другие символы, общие для многих национальных алфавитах;
127 — управляющий символ, не использующийся в тексте;
128..255 — национальные алфавиты и их специальные символы языков.
Первая часть таблицы (32..127) фиксированная. Вторая часть таблицы (128..255) является изменяемой и для каждой страны со своей азбукой, разработана своя последняя часть таблицы. Для России в операционной системе Windows наш стандарт называется «CP1251» (таблицу кодов смотри ниже).
Перевод текста в память компьютера заключается в определении соответствия символа и числа, включая пробелы и все знаки пунктуации как отдельные символы. Последовательность этих чисел и есть текст.
Такая схема порождает проблему совместимости: файл созданный в одном национальном стандарте, будет прочитан не корректно в другом стандарте. Другая проблема — невозможность печати одновременно разными языками, например, русскими и греческими в одном документе.
Unicode
Для снятия ограничений применения кодировки ASCII был разработан новый стандарт «Unicode». Его отличие состоит в том, что символ кодируется 2-х байтовым числом. Количество символов составляет 216, или 65536 символов. В одной кодовой таблице появилась возможность применить все основные национальные стандарты.
Принцип кодирования остался прежним, только числа стали не однобайтовыми (0..255), а двух байтовыми (0..65536). Размер данных на диске при использовании стандарта «Unicode» вырос в 2 раза по сравнению с ASCII, но появилась возможность использовать разные алфавиты в одном документе.
Первая неизменяемая часть кодовой таблицы ASCII (32..127)
Код | Символ | Код | Символ | Код | Символ | Код | Символ |
32 | пробел | 56 | 8 | 80 | P | 104 | h |
33 | ! | 57 | 9 | 81 | Q | 105 | i |
34 | “ | 58 | : | 82 | R | 106 | j |
35 | # | 59 | ; | 83 | S | 107 | k |
36 | $ | 60 | < | 84 | T | 108 | l |
37 | % | 61 | = | 85 | U | 109 | m |
38 | & | 62 | > | 86 | V | 110 | n |
39 | ‘ | 63 | ? | 87 | W | 111 | o |
40 | ( | 64 | @ | 88 | X | 112 | p |
41 | ) | 65 | A | 89 | Y | 113 | q |
42 | * | 66 | B | 90 | Z | 114 | r |
43 | + | 67 | C | 91 | [ | 115 | s |
44 | , | 68 | D | 92 | \ | 116 | t |
45 | — | 69 | E | 93 | ] | 117 | u |
46 | . | 118 | v | ||||
47 | / | 71 | G | 95 | _ | 119 | w |
48 | 0 | 72 | H | 96 | ` | 120 | x |
49 | 1 | 73 | I | 97 | a | 121 | y |
50 | 2 | 74 | J | 98 | b | 122 | z |
51 | 3 | 75 | K | 99 | c | 123 | { |
52 | 4 | 76 | L | 100 | d | 124 | | |
53 | 5 | 77 | M | 101 | e | 125 | } |
54 | 6 | 78 | N | 102 | f | 126 | ~ |
55 | 7 | 79 | O | 103 | g | 127 | del |
Вторая изменяемая часть кодовой таблицы ASCII (128..255)
Код | Символ | Код | Символ | Код | Символ | Код | Символ |
128 | Ђ | 160 | 192 | А | 224 | а | |
129 | Ѓ | 161 | Ў | 193 | Б | 225 | б |
130 | ‚ | 162 | ў | 194 | В | 226 | в |
131 | ѓ | 163 | Ј | 195 | Г | 227 | г |
132 | „ | 164 | ¤ | 196 | Д | 228 | д |
133 | … | 165 | Ґ | 197 | Е | 229 | е |
134 | † | 166 | ¦ | 198 | Ж | 230 | ж |
135 | ‡ | 167 | § | 199 | З | 231 | з |
136 | € | 168 | Ё | 200 | И | 232 | и |
137 | ‰ | 169 | © | 201 | Й | 233 | й |
138 | Љ | 170 | Є | 202 | К | 234 | к |
139 | ‹ | 171 | « | 203 | Л | 235 | л |
140 | Њ | 172 | ¬ | 204 | М | 236 | м |
141 | Ќ | 173 | — | 205 | Н | 237 | н |
142 | Ћ | 174 | ® | 206 | О | 238 | о |
143 | Џ | 175 | Ї | 207 | П | 239 | п |
144 | ђ | 176 | ° | 208 | Р | 240 | р |
145 | ‘ | 177 | ± | 209 | С | 241 | с |
146 | ’ | 178 | І | 210 | Т | 242 | т |
147 | “ | 179 | і | 211 | У | 243 | у |
148 | ” | 180 | ґ | 212 | Ф | 244 | ф |
149 | • | 181 | μ | 213 | Х | 245 | х |
150 | – | 182 | ¶ | 214 | Ц | 246 | ц |
151 | — | 183 | · | 215 | Ч | 247 | ч |
152 | _ | 184 | ™ | 216 | Ш | 248 | ш |
153 | ё | 185 | № | 217 | Щ | 249 | щ |
154 | љ | 186 | є | 218 | Ъ | 250 | ъ |
155 | › | 187 | » | 219 | Ы | 251 | ы |
156 | њ | 188 | ј | 220 | Ь | 252 | ь |
157 | ќ | 189 | Ѕ | 221 | Э | 253 | э |
158 | ћ | 190 | ѕ | 222 | Ю | 254 | ю |
159 | џ | 191 | ї | 223 | Я | 255 | я |
Пример: Записать слово «Hard» с применением стандарта ASCII.
Расчет.
Переведем его в десятичные числа согласно кодировке ASCII. Поскольку в слове только латиница, то применим первую половину таблицы кодов:
H — 72
a — 97
r — 114
d — 100
Далее переведем получившиеся числа в 2-ную и 16-ную систему счисления (см. раздел «Двоичная система счисления» и «Шеснадцатеричная система счисления»).
Примечание. Поскольку числа соответствуют байтам, то количество разрядов в каждом числе должно быть равным 8, если получается меньше, то необходимо добавить «0» в качестве старших разрядов до 8:
Система счисления | |
2-ная | 16-ная |
7210 — 010010002 9710 — 011000012 11410 — 011100102 10010 — 011001002 | 7210 — 4816 9710 — 6116 11410 — 7216 10010 — 6416 |
Запишем полученные разряды в одну строчку, слева направо. Полученная последовательность и есть требуемый ответ:
H | a | r | d |
01001000 | 01100001 | 01110010 | 01100100 |
48 | 61 | 72 | 64 |
Ответ: 01001000011000010111001001100100
48617264
15
Блог учителя информатики: Кодирование текстовой информации
Сегодня я хочу поговорить о кодировках. Зачем вообще нужны кодирование текстов и почему это так важно? Какие кодировки текста существуют и какие из них следует использовать?
У вас встречалась ситуация, когда вы получаете электронное письмо, но не можете его прочитать – вместо текста идут какие-то непонятные знаки? То же самое случается и в интернете – открываете страницу, а разобрать ничего не возможно. Причем заметьте, подобное происходит именно с русским текстом, с английским подобные проблемы маловероятны. Причина проблем – открытие файла в неверной кодировке.
Соответствие между набором символов и набором числовых значений называется кодировкой символа.
В процессе вывода символа на экран производится обратная операция – декодирование, т.е. преобразование кода символа в изображение.
Присвоенный каждому символу конкретный числовой код фиксируется в кодовых таблицах. Причем, в разных таблицах одному и тому же символу могут соответствовать разные числовые коды. Обычно перекодированием текста занимаются специальные программы-конвертеры, они встроены в большинство приложений.
Зачем нужны кодировки
Символы на экране вашего компьютера формируются на основе двух вещей — наборов векторных форм (представлений) всевозможных символов (они находятся в файлах со шрифтами, которые установлены на вашем компьютере) и кода, который позволяет выдернуть из этого набора векторных форм (файла шрифта) именно тот символ, который нужно будет вставить в нужное место.
Кодировка ASCII
Для начала немного посчитаем. Помните, что такое бит? Это минимальный носитель информации, ноль или один. А байт содержит восемь битов. Сколько может быть комбинаций из нулей и единиц длины 8? Ответ – 2*2*2*2*2*2*2*2=256. Именно столько значений может принимать один байт. Иногда еще байт называют символом – потому что как раз для кодировки символа и стали использовать один байт. Даже меньше, изначально была придумана кодировка ASCII, которая использовала 7 битов – в первые 128 значений можно было вольготно разместить английский алфавит в обоих регистрах, диакритические знаки, цифры и набор спец-символов. И эта кодировка действительно стала универсальной, поэтому англоязычные пользователи крайне редко могут испытывать проблемы с кодировкой.
Кодировка ASCII (American Standard Code for Information Interchange, которая по русски обычно произносится как «аски») описывает первые 128 символов из наиболее часто используемых англоязычными пользователями — латинские буквы, арабские цифры и знаки препинания. Так же еще в эти 128 символов кодировки ASCII попадали некоторые служебные символы, навроде скобок, решеток, звездочек и т.п. Именно эти 128 символов из первоначального вариант ASCII стали стандартом, и в любой другой кодировке текста вы их обязательно встретите и стоять они будут именно в таком порядке. Но дело в том, что с помощью одного байта информации можно закодировать не 128, а целых 256 различных значений (двойка в степени восемь равняется 256), поэтому вслед за базовой версией ASCII появился целый ряд расширенных кодировок ASCII, в которых можно было кроме 128 основных символов закодировать еще и символы национальной кодировки (например, русской).
Кодировка КОИ-8R
Принцип работы кодировки KOI-8R такой— каждый символ текста кодируется одним единственным байтом.
Среди особенностей кодировки KOI-8R можно отметить то, что русские буквы в ее таблице идут не в алфавитном порядке. В кодировке KOI-8R русские буквы расположены в тех же ячейках таблицы, что и созвучные им буквы латинского алфавита из первой части таблицы ASCII. Это было сделано для удобства перехода с русских символов на латинские путем отбрасывания всего одного бита (два в седьмой степени или 128).
Кодировка Unicode
Перейдем к кириллице. Для нее стали использовать вторую половину кодовой таблицы – символы 129-256. Однако так сложилось, что различные кодировки были изобретены независимо – одни изобретатели располагали буквы, стремясь к соответствию расположения на пишущих машинках, другие – к тому, чтобы одинаково выглядящие кириллические и латинские буквы находились на расстоянии в 128 (что приводило к тому, что даже программы, не умевшие работать со второй половиной таблицы, более-менее читаемо отображали русский текст). Были и другие идеи; появление Windows также принесло свою кодировку. Но главное, такая кодировка принципиально не могла стать универсальной, так как если латиница была нужна везде (хотя бы для командной строки), то кириллица была лишь одним из национальных алфавитов.
У единой, потенциально универсальной кодировки, существует название: Unicode, и придумана она была уже давно, в 1991 году. В Юникоде используется 6 байтов для отображения символа.
Например, в операционной системе Windows вы можете пройти по пути Пуск — Программы — Стандартные — Служебные — Таблица символов. В результате откроется таблица с векторными формами всех установленных у вас в системе шрифтов. Если вы выберите в Дополнительных параметрах набор символов Юникод, то сможете увидеть для каждого шрифта в отдельности весь ассортимент входящих в него символов. Кстати, щелкнув по любому из этих символов вы сможете увидеть его двухбайтовый код в кодировке UTF 16, состоящий из четырех шестнадцатеричных цифр.
Кодировки кириллицы
Как правило, для хранения кода символа используется 1 байт (8 битов).
Поэтому коды символов могут принимать значение от 0 до 255. Такие кодировки называют однобайтными. Они позволяют использовать 256 символов (2 в восьмой степени равно 256). Таблица однобайтных кодов символов ASCII состоит из двух частей. Первая часть таблицы ASCII-кодов (от 0 до 127) стандартна для всех компьютеров и содержит:
- коды управляющих символов,
- коды цифр, арифметических операций, знаков препинания,
- некоторые специальные символы,
- коды больших и маленьких латинских букв.
- коды букв национального алфавита,
- коды некоторых математических символов,
- коды символов псевдографики.
Для русских букв используются такие различные кодовые таблицы: КОИ-8, ISO, Mac, CP1251, CP866.
В последнее время широкое распространение получил новый международный стандарт Unicode.
В Unicode отводится по 2 байта (16 битов) для кодирования каждого символа.
Поэтому с его помощью можно закодировать 65536 различных символов (2 в шестнадцатой степени равно 65536). Коды символов могут принимать значение от 0 до 65535.
Примеры решения задач
1. С помощью кодировки Unicode закодирована следующая фраза: Я хочу поступить в университет!Оцените информационный объем этой фразы.
Решение:
В данной фразе содержится 31 символ (включая пробелы и знак препинания). Поскольку в кодировке Unicode каждому символу отводится 2 байта памяти, для всей фразы понадобится 31*2 = 62 байта или 31*2*8 = 496 битов.
2. Статья, набранная на компьютере, содержит 8 страниц, на каждой странице 40 строк, в каждой строке 64 символа. В одном из представлений Unicode каждый символ кодируется 16 битами. Определите информационный объем статьи в этом варианте Unicode. Выберите верный ответ из предложенных: а) 320 байт, б) 35 Кбайт , в) 640 байт, г) 40 Кбайт.
Определим количество символов: 8*40*64 = 20480. Поскольку в кодировке Unicode каждому символу отводится 16 битов памяти, для всей фразы понадобится 20480*16 = 327680 битов.
Переведем полученное значение в байты. Т.к. 8 бит = 1 байт, то 327680 : 8 = 40960 байт
Теперь в Кбайты. Т.к. 1024 байт = 1 Кбайт, то 40960 : 1024 = 40 Кбайт.
Из предложенных вариантов подходит вариант г) 40 Кбайт.
Решите самостоятельно
- В кодировке КОИ-8 каждый символ кодируется 1 байтом. Определите информационный объем сообщения из 20 символов в этой кодировке. Варианты ответов: а) 20 бит, б) 80 бит, в) 160 бит, г) 320 бит.
- В кодировке Unicode на каждый символ отводится 2 байта. Определите информационный объем слова из 24 символов в этой кодировке. Найдите верный ответ: а) 384 бита, б) 192 бита, в) 256 бит, г) 48 бит.
Урок №2. Тексты. Кодирование
Май 10 2013
Как решать некоторые задачи разделов A и B экзамена по информатике
Урок №2. Тексты. Кодирование
В основе каждого текста лежит алфавит – конечное множество символов. В основе текстов на русском языке лежит алфавит, называемый кириллицей, состоящий из 33 строчных и 33 заглавных букв алфавита. Тексты английского языка построены на основе латиницы – алфавита, содержащего 26 строчных и 26 заглавных букв. Конечно алфавит, на основе которого строятся тексты на естественных языках, содержит не только буквы, но и цифры, знаки операций и множество других специальных символов.
Пусть задан алфавит T, содержащий m символов:
T = { t1, t2, …tm}
Словом S в алфавите T называют любую последовательность символов алфавита:
S = s1s2…sk,
где si – это символы алфавита. Число символов в слове – k называют длиной слова.
Справедливо утверждение:
Число различных слов длины k, которые можно построить в алфавите из m символов, равно: N = mk
Справедливость утверждения легко доказывается по индукции.
Базис индукции: при k = 1, утверждение справедливо, поскольку словами длины 1 являются m символов алфавита.
Шаг индукции: Пусть утверждение справедливо при некотором k. Это означает, что построено mk слов длины k. Из каждого слова можно построить m новых слов длины k +1, приписывая к слову поочерёдно m символов алфавита. Таким образом, слов длины k + 1 будет:
N = mk * m = mk+1
Это простое, но важное утверждение, которое в том или ином виде используется при решении различных задач.
Алфавит компьютера
Тексты, которые хранятся в памяти компьютера, используют один из самых примитивных алфавитов, состоящий всего из двух символов:
T2 = {0, 1}
С другой стороны мы знаем, что в памяти компьютера можно хранить не только тексты на различных естественных языках, но и графику, музыку и другую информацию различного вида. Как такое возможно? Разберемся с текстами. Пусть есть два алфавита – T, состоящий из m символов и алфавит T2. Представление текстов в алфавите T текстами в алфавите T2 называется кодированием. Простейший способ кодирования состоит в том, чтобы символы алфавита T кодировать словами конечной длины алфавита T2. Умея кодировать каждый символ, можно кодировать любой текст символ за символом.
Какова должна быть минимальная длина слов в алфавите T2, чтобы было возможно этими словами закодировать алфавит из m символов? Очевидно, что длина может быть определена из условия:
2k >= m
Если, например, m = 30, то наименьшее возможное значение k равно 5.
Долгое время при работе с текстами, сохраняемыми в компьютере, использовался код ASCII, в котором каждый символ алфавита кодировался словом из 8 бит (одним байтом). Такой алфавит, содержащий 256 различных символов, мог включать латиницу и кириллицу, цифры, знаки операций, знаки препинания, скобки и другие символы. Но все-таки этого алфавита явно недостаточно, чтобы можно было хранить в памяти компьютера тексты на любых естественных языках. Чтобы такое было возможно, необходимо, чтобы алфавит включал алфавиты всех известных естественных языков, в том числе алфавит украинского языка, готику, греческий алфавит, алфавит языка иврит, арабского языка, китайские и японские иероглифы.
В сегодняшних компьютерах для хранения текстов используется кодировка из двух байтов, называемая UNICODE кодировкой, позволяющая словами из 16 битов кодировать алфавит, содержащий 216 — 65536 символов. Для большинства существующих естественных языков такого алфавита хватает для представления текстов, записанных на этих языках.
Задача 9:
Автомобильный номер состоит из 7 символов. В качестве символов используются 30 букв и 10 цифр. Символ кодируется минимально возможным набором битов. Номер представляется целым числом байтов. Какую память требуется иметь для хранения 1000 номеров.
Ответ: Примерно 6 Кб.
Решение: Алфавит для записи текстов, представляющих номера автомобилей, содержит 40 символов (30 букв и 10 цифр). Для кодировки такого алфавита потребуются двоичные слова длины 6 (26 > 40). Для кодировки всего номера потребуется 6*7 = 42 бита. Округляя в большую сторону до целого числа байтов, получим, что для хранения одного номера потребуется 6 байтов. Для хранения 1000 номеров достаточно 6 Кб.
Задача 10:
В командной олимпиаде по информатике участвуют ученики из школ, номера которых заданы двузначными цифрами. В команде может быть не более 7 учеников. Какой минимальный объем памяти потребуется для хранения 500 номеров участников олимпиады, если каждый номер представляется целым числом байтов?
Ответ: Достаточно 1 Кб.
Решение: Номер участника может состоять из номера школы и номера участника в данной школе. Для 100 номеров школ достаточно 7-и битов (27 > 100). Для номера участника в школе достаточно 3-х битов (23 > 7). Поэтому для хранения номера участника достаточно 10 битов. Округляя в большую сторону до целого числа байтов, получим, что 2-х байтов достаточно для хранения номера. Для хранения 500 номеров достаточно одного килобайта.
Задача 11:
Алфавит состоит из 4-х букв {М, У, Х, А} Слова длины 5 перечисляются в лексикографическом порядке. Нумерация слов начинается с единицы. Какое слово в этом перечислении стоит под номером 1016, под номером 365?
Ответ: ХХХМХ; ММУХА
Решение: Число различных слов длины 5 в 4-х буквенном алфавите равно 45 = 210 = 1024. При перечислении их в алфавитном (лексикографическом) порядке под номером 1 стоит слово ААААА, под номером 1024 – слово ХХХХХ. В задачах экзамена ЕГЭ обычно требуется указать слово, стоящее близко к концу перечисления, что имеет место в нашей задаче, в которой требуется назвать слово под номером 1016, стоящее в первом десятке с конца перечисления. Поэтому для решения задачи достаточно выписать десять слов в обратном лексикографическом порядке, что и дает слово ХХХМХ.
Для ответа на второй вопрос, где требуется найти слово, стоящее в середине перечисления, такой явный способ выписывания слов не подходит. В этом случае следует применять более общий подход, применимый для всех случаев. Для его понимания нужно вспомнить системы счисления.
Поставим в соответствие буквам алфавита цифры (А – 0, М – 1, У – 2, Х -3). При задании этого соответствия учитывается принятый порядок следования букв в алфавите. Число букв задает число используемых цифр, а тем самым задает основание системы счисления. Введенное соответствие букв и цифр порождает соответствие между словами в алфавите и числами в соответствующей системе счисления, в нашем случае – четверичной системе счисления. При лексикографическом перечислении слов длины k слову, стоящему под номером N, соответствует число N-1 в четверичной системе счисления, содержащее k цифр, включая незначащие нули. Так, слову под номером 1, состоящему из 5 букв, соответствует число 0, записанное как 00000, или, после замены цифр буквами, — ААААА. Поэтому для решения задачи, зная N, достаточно получить запись числа N-1 в четверичной системе, а затем заменить цифры буквами.
Получим решение задачи этим способом для N = 1016 и N = 365.
N — 1 = 1015 = 3* 44 + 3* 43 +3* 42 + 1* 41 + 3 = 333134 = ХХХМХ
N -1 = 364 = 1* 44 + 1* 43 +2* 42 +3* 41 + 0 = 112304 = ММУХА
Задача 12:
Алфавит состоит из 3-х букв {А,М, П} Слова длины 4 перечисляются в лексикографическом порядке. Нумерация слов начинается с единицы. Под каким номером стоит слово МАМА, слово — ПАПА?
Ответ: 31; 61
Решение: В троичной системе слову МАМА соответствует число 10103 = 33 + 3 = 30. В перечислении, где нумерация начинается с 1, номер этого слова равен 31.
Слову ПАПА соответствует число 20203 = 60.
Кодирование словами переменной длины
Кодировка символов алфавита T словами алфавита Т2 фиксированной длины k имеет то преимущество, что закодированный текст легко поддается расшифровке – декодированию. Действительно, достаточно закодированный текст разбить на группы длины k, и каждой группе поставить в соответствие символ алфавита. Недостатком такого способа является некоторая неэффективность процедуры кодирования, — каждому символу алфавита всегда соответствует k битов алфавита Т2. Память компьютера достаточно дешевая, поэтому жертвуют неэффективностью использования памяти ради удобства декодирования.
В других ситуациях эффективность важнее удобства декодирования. Примерами являются азбука Брайля, азбука Морзе. В азбуке Морзе, где для передачи информации используется алфавит из двух символов – точки и тире, для однозначного декодирования вводится третий символ – пауза. При передаче данных по телеграфу, использующему азбуку Морзе, точке, тире и паузе соответствуют сигналы разной длительности.
Рассмотрим пример неоднозначного кодирования. Пусть у нас есть алфавит из 3-х символов – А, М, П. Введем следующую кодировку: А – 0, М – 1, П – 10. Рассмотрим закодированный текст: 1010. Этому тексту соответствуют два слова – МАМА и ПП. Как видите, введенная кодировка не обеспечивает однозначное декодирование.
Можно ли при использования кодировки словами переменной длины наложить ограничения на способ кодирования, чтобы декодирование было однозначным? Ответ положителен. Если при кодировании выполняется условие Фано, то декодирование однозначно. Кодирование называется префиксным, если при кодировании существует пара символов, такая, что код одного символа является префиксом кода другого символа. В нашем примере кодирование является префиксным, поскольку для символов М и П код символа М является префиксом (началом) кода символа П. Условие Фано выполняется, если кодирование не является префиксным. Условие Фано является достаточным условием для однозначного декодирования. Оно не является необходимым условием.
Рассмотрим несколько задач, решение которых предполагает использование условия Фано.
Задача 13:
Для трехбуквенного алфавита {А, М, П} используется кодировка А – 01, М – 10, П – 001. Какой код минимальной длины следует задать для кодировки буквы Т, добавляемой в алфавит?
Ответ: Т – 11.
Решение: Используемая кодировка удовлетворяет условию Фано, — ни один код не является префиксом другого кода, что гарантирует однозначность декодирования. Для нового символа, добавляемого в алфавит, нельзя использовать код, состоящий из одного символа, поскольку будет нарушено условие Фано. Для кода, состоящего из двух символов, возможен только один вариант, удовлетворяющий условию Фано, — Т – 11.
Задача 14:
Для четырехбуквенного алфавита {А, М, П, Т} используется кодировка А – 01, М – 10, П – 001, Т — 11. Можно ли уменьшить длину кода одного из символов, сохраняя однозначность декодирования?
Ответ: Можно. П – 00.
Решение: Используемая кодировка удовлетворяет условию Фано, — ни один код не является префиксом другого кода, что гарантирует однозначность декодирования. Не нарушая условия Фано, для кодирования буквы П можно использовать код 00. Заметьте, в этом случае все символы кодируются словами постоянной длины. Для такой кодировки условие Фано выполняется автоматически, поскольку все слова различны и имеют одинаковую длину, так что ни одно из них не может быть префиксом другого слова.
10 задач для самостоятельной работы
- Представьте в кодировке Unicode следующий текст: «Иван да Марья».
Напомню правила кодировки:
- За исключением буквы «ё» кодировка алфавита кириллицы плотная. Это означает, что код буквы, следующей в алфавите, на единицу больше кода предшествующей буквы.
- Кодировка больших букв предшествует кодировке малых букв.
- Кодировка ASCII (первые 128 символов) является подмножеством кодировки Unicode. В обеих кодировках код пробела равен 20 в шестнадцатеричной системе (32 в десятичной системе).
- Код первой буквы алфавита кириллицы в кодировке Unicode равен 410 в шестнадцатеричной системе.
- Определите способ шифрования и декодируйте следующий текст: «молымушамалымамам».
- Декодируйте текст, зашифрованный кодом Цезаря:
«цщччропеднареоуъфцтёшорёетёшктёшорё».
Исходный текст содержал пробелы и символы алфавита кириллицы. При шифровании заглавные и строчные буквы не различались. Символ «пробела» считался предшествующим символам алфавита. - Кодом Грея называется код, в котором коды каждых двух соседних символов отличаются только в одном разряде. Первый и последний символы считаются соседними. Предложите код Грея для кодирования цифр шестнадцатеричной системы счисления.
- В алфавите из четырех букв {А, У, М, П} частоты вхождения символов алфавита в тексты различны и составляют соответственно {0,5; 0,25; 0,125; 0,125}. Постройте неравномерный двоичный код, соблюдая условие Фано.
- В биоинформатике генетический код рассматривается как последовательность слов, называемых кодонами или триплетами. Каждый триплет представляет слово длины 3 в алфавите из четырех букв { А, Ц, Г, Т}. Содержательно, каждый символ алфавита соответствует одному из четырех нуклеотидов {аденин, цитозин, гуанин, тимин}. Содержательно, каждый триплет однозначно задает одну из двадцати стандартных аминокислот, из которых синтезируются белки. Поскольку различных аминокислот 20, а триплетов 64, то возникает избыточность, — разные триплеты могут задавать одну и ту же аминокислоту. Какая кислота имеет максимальную степень избыточности и сколько триплетов задают эту кислоту? Найдите эту информацию в интернете.
- Для идентификации автомобилей использовались семизначные цифровые номера. Две последние цифры задавали номер региона, пять первых цифр задавали номер автомобиля в данном регионе. В связи с ростом автомобильного парка номеров стало не хватать, и было принято решение изменить нумерацию, добавив буквенные символы. Все старые номера автомобилей сохранялись. Два последних символа по-прежнему задавали номер региона. Пять первых символов могли быть буквенными. Для благозвучности номера и его лучшего запоминания нечетные символы номера составлялись из 20 согласных букв, четные символы номера – второй и четвертый – могли быть одной из 7 гласных букв. Во сколько раз такая реформа увеличивала число номеров?
- Все старые номера автомобилей (смотри задачу 7) хранились в памяти компьютера. Сколько памяти требуется отвести для хранения новых номеров, если для каждого номера отводится целое число байтов, а каждый символ номера с учетом его специфики кодируется минимально возможным числом битов?
- В алфавите из пяти символов {Д, Е, И, Л, Р} слова выписаны в лексикографическом порядке. Какие слова стоят под номерами 334 и 2134?
- Память фотоаппарата составляет 512 Мб. Вы хотите хранить в памяти 1000 снимков. Какое возможное разрешение следует установить для снимков (1024 * 1024, 1024 * 512, 512 * 512, 512 * 256, 256 * 256, 128* 128)? Для хранения цвета одной точки используется схема RGB, где каждый оттенок красного, зеленого и голубого цвета задается числом в пределах от 0 до 255.
Ответы к задачам
- 41843243043D204344302041C43044044C44F
- Текст: «Мама мыла Машу мылом». При кодировании пробелы игнорируются. Порядок слов меняется на обратный. Заглавные и строчные буквы не различаются. Порядок букв в каждом слове меняется на обратный.
- Текст: «Русский язык информатика математика». Константа кода Цезаря, определяющая сдвиг по алфавиту, равна 6.
- 0 → 0000; 1 → 0001; 2 → 0011; 3 → 0010; 4 → 0110; 5 → 0111; 6 → 0101; 7 → 0100; 8 → 1100; 9 → 1101; A → 1111; B → 1110; C → 1010; D → 1011;
E → 1001; F → 1000; - Чаще встречаемые символы кодируются короткими кодовыми словами. Код, удовлетворяющий условию Фано, может быть следующим:
А → 0; У → 10; М → 110; П → 111; - Такой кислотой является, например, серин, задаваемый 6-ю различными кодонами.
- Почти в пять раз, k = (203 *72 +105) /105.
- Примерно 160 Мб. (4 байта на номер).
- ДИЛЕР и ЛИДЕР
- 512 * 256
Скачать урок №2 можно здесь.
Автор: bivant • Информатика, ЕГЭ. • 0
python — Как правильно кодировать немецкие символы в запросах-ответах с сайта?
Я хочу извлечь данные с transfermarkt.de. Для получения данных я использую библиотеку запросов. Но независимо от того, какую кодировку я использую, немецкие специальные символы не разбираются правильно.
Сайт предоставляет UTF-8 в качестве кодировки в заголовке, но автоматическая кодировка в запросах выдает неправильные специальные символы. Сравнивая, я выяснил, что r.text выглядит абсолютно так же, как r.контент при использовании UTF-8.
Итак, я много читал о кодировании (да, я думаю, что теперь у меня есть Unicode-вещь ;-)) и пробовал разные кодировки с запросами — вот мой тестовый код:
запросов на импорт
ссылка = 'https://www.transfermarkt.de/fc-bayern-munchen/kader/verein/27/saison_id/2017'
user_agent = 'Mozilla / 5.0 (Windows NT 6.1; Win64; x64; rv: 47.0) Gecko / 20100101 Firefox / 47.0'
r = requests.get (ссылка, заголовки = {"User-Agent": user_agent})
print ('--------------------------------- СОДЕРЖАНИЕ ----------')
печать (r.содержание [4500: 5000])
r.encoding = 'UTF-8'
print ('------------------------------- ТЕКСТ UTF8 ----------')
печать (r.text [4500: 5000])
r.encoding = 'iso-8859-1'
print ('-------------------------------- ТЕКСТ iso-8859-1 --------- - ')
печать (r.text [4500: 5000])
Это дает следующий результат:
----------------------------------------- СОДЕРЖАНИЕ ------ ----
ФК Бавария Менхен - Кадер, деталь 17/18 "/>
Как видите, "ü" слова "München" неправильно отображается в отрывке. Кто-нибудь знает, что я мог бы сделать по-другому?
Извлечь содержимое из запроса. - содержание • httr
В настоящее время есть три способа получить содержимое запроса:
как необработанный объект ( as = "raw"
), как вектор символов,
( as = "text"
) и, если возможно, преобразовано в объект R,
( as = "parsed"
).Если как
не указано, содержимое
делает все возможное, чтобы угадать, какой результат является наиболее подходящим.
содержимое (x, as = NULL, тип = NULL, кодировка = NULL, ...)
Аргументы
x | объект запроса |
---|---|
как | желаемый тип вывода: |
тип | Тип MIME (он же Интернет-тип мультимедиа), используемый для переопределения тип контента, возвращаемый сервером. Видеть https://en.wikipedia.org/wiki/Internet_media_type для списка общие типы. |
кодировка | Для текста переопределяет кодировку или Latin1 (ISO-8859-1) по умолчанию, если вы знаете, что сервер возвращает неправильную кодировку как кодировка в типе содержимого. Используется для текстовых и проанализированных выходных данных. |
... | Другие параметры, передаваемые функциям синтаксического анализа, если |
Значение
Для "сырого", необработанный вектор.
Для «текста» - вектор символов длиной 1. Вектор символов всегда
перекодирован в UTF-8. Если эта кодировка не работает (обычно из-за того, что страница
объявляет неправильную кодировку), content ()
вернет NA
.
Для «авто» - проанализированный объект R.
Детали
content
в настоящее время знает о следующих типах mime:
as = "parsed"
предоставляется только для удобства: если тип, который вы
пытается разобрать недоступно, используйте as = "text"
и выполните синтаксический анализ
сам.
ПРЕДУПРЕЖДЕНИЕ
При использовании content ()
в пакете НЕ используйте на as = "parsed"
.
Вместо этого проверьте mime-тип, который вы ожидаете, а затем проанализируйте себя.Это безопаснее, так как вы не получите информативной информации, если API изменится, и
вы защитите себя от изменений в httr.
См. Также
Примеры
r <- POST ("http://httpbin.org/post", body = list (a = 1, b = 2)) content (r) # автоматически анализирует JSON#> $ args #> именованный список () #> #> $ data #> [1] "" #> #> $ files #> именованный список () #> #> $ form #> $ form $ a #> [1] "1" #> #> $ form $ b #> [1] "2" #> #> #> $ заголовки #> $ headers $ Принять #> [1] "приложение / json, текст / xml, приложение / xml, * / *" #> #> $ headers $ `Accept-Encoding` #> [1] "deflate, gzip" #> #> $ заголовки $ `Content-Length` #> [1] "228" #> #> $ headers $ `Content-Type` #> [1] "multipart / form-data; Border = ------------------------ 3824d7442b87926f" #> #> $ headers $ Host #> [1] "httpbin.org " #> #> $ заголовки $ `User-Agent` #> [1] "libcurl / 7.58.0 r-curl / 4.3 httr / 1.4.2.9000" #> #> $ заголовки $ `X-Amzn-Trace-Id` #> [1] "Root = 1-60620b03-5ed7f35a3651165527501361" #> #> #> $ json #> NULL #> #> $ origin #> [1] "52.255.165.122" #> #> $ url #> [1] "http://httpbin.org/post" #>
cat (content (r, "text"), "\ n") # text content#> Кодировка не указана: по умолчанию используется UTF-8.
#> { #> "args": {}, #> "данные": "", #> "файлы": {}, #> "form": { #> "a": "1", #> "b": "2" #>}, #> "заголовки": { #> "Принять": "приложение / json, текст / xml, приложение / xml, * / *", #> "Accept-Encoding": "deflate, gzip", #> "Content-Length": "228", #> "Content-Type": "multipart / form-data; Border = ------------------------ 3824d7442b87926f", #> "Хост": "httpbin.org ", #> "User-Agent": "libcurl / 7.58.0 r-curl / 4.3 httr / 1.4.2.9000", #> "X-Amzn-Trace-Id": "Root = 1-60620b03-5ed7f35a3651165527501361" #>}, #> "json": null, #> "origin": "52.255.165.122", #> "url": "http://httpbin.org/post" #>} #>
content (r, "raw") # сырые байты с сервера
#> [1] 7b 0a 20 20 22 61 72 67 73 22 3a 20 7b 7d 2c 20 0a 20 20 22 64 61 74 61 22 #> [26] 3a 20 22 22 2c 20 0a 20 20 22 66 69 6c 65 73 22 3a 20 7b 7d 2c 20 0a 20 20 #> [51] 22 66 6f 72 6d 22 3a 20 7b 0a 20 20 20 20 22 61 22 3a 20 22 31 22 2c 20 0a #> [76] 20 20 20 20 22 62 22 3a 20 22 32 22 0a 20 20 7d 2c 20 0a 20 20 22 68 65 61 #> [101] 64 65 72 73 22 3a 20 7b 0a 20 20 20 20 22 41 63 63 65 70 74 22 3a 20 22 61 #> [126] 70 70 6c 69 63 61 74 69 6f 6e 2f 6a 73 6f 6e 2c 20 74 65 78 74 2f 78 6d 6c #> [151] 2c 20 61 70 70 6c 69 63 61 74 69 6f 6e 2f 78 6d 6c 2c 20 2a 2f 2a 22 2c 20 #> [176] 0a 20 20 20 20 22 41 63 63 65 70 74 2d 45 6e 63 6f 64 69 6e 67 22 3a 20 22 #> [201] 64 65 66 6c 61 74 65 2c 20 67 7a 69 70 22 2c 20 0a 20 20 20 20 22 43 6f 6e #> [226] 74 65 6e 74 2d 4c 65 6e 67 74 68 22 3a 20 22 32 32 38 22 2c 20 0a 20 20 20 #> [251] 20 22 43 6f 6e 74 65 6e 74 2d 54 79 70 65 22 3a 20 22 6d 75 6c 74 69 70 61 #> [276] 72 74 2f 66 6f 72 6d 2d 64 61 74 61 3b 20 62 6f 75 6e 64 61 72 79 3d 2d 2d #> [301] 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 33 38 32 #> [326] 34 64 37 34 34 32 62 38 37 39 32 36 66 22 2c 20 0a 20 20 20 20 22 48 6f 73 #> [351] 74 22 3a 20 22 68 74 74 70 62 69 6e 2e 6f 72 67 22 2c 20 0a 20 20 20 20 22 #> [376] 55 73 65 72 2d 41 67 65 6e 74 22 3a 20 22 6c 69 62 63 75 72 6c 2f 37 2e 35 #> [401] 38 2e 30 20 72 2d 63 75 72 6c 2f 34 2e 33 20 68 74 74 72 2f 31 2e 34 2e 32 #> [426] 2e 39 30 30 30 22 2c 20 0a 20 20 20 20 22 58 2d 41 6d 7a 6e 2d 54 72 61 63 #> [451] 65 2d 49 64 22 3a 20 22 52 6f 6f 74 3d 31 2d 36 30 36 32 30 62 30 33 2d 35 #> [476] 65 64 37 66 33 35 61 33 36 35 31 31 36 35 35 32 37 35 30 31 33 36 31 22 0a #> [501] 20 20 7d 2c 20 0a 20 20 22 6a 73 6f 6e 22 3a 20 6e 75 6c 6c 2c 20 0a 20 20 #> [526] 22 6f 72 69 67 69 6e 22 3a 20 22 35 32 2e 32 35 35 2e 31 36 35 2e 31 32 32 #> [551] 22 2c 20 0a 20 20 22 75 72 6c 22 3a 20 22 68 74 74 70 3a 2f 2f 68 74 74 70 #> [576] 62 69 6e 2e 6f 72 67 2f 70 6f 73 74 22 0a 7d 0a
rlogo <- content (GET ("http: // cran.r-project.org/Rlogo.jpg ")) сюжет (0: 1, 0: 1, type = "n")
Руководство по Unicode, UTF-8 и строкам в Python | автор: Санкет Гупта
Давайте рассмотрим основные концепции струнных инструментов, которые выведут ваше понимание на новый уровень.
Строки - один из наиболее распространенных типов данных в Python. Они используются для работы с текстовыми данными любого типа. Область обработки естественного языка построена на некоторой обработке текста и строк. Важно знать, как работают строки в Python.Со строками обычно легко работать, когда они состоят из английских символов ASCII, но «проблемы» возникают, когда мы вводим символы, отличные от ASCII, которые становятся все более распространенными в современном мире, особенно. с появлением эмодзи и т. д.
Давайте расшифруем, что скрыто в строках Многие программисты используют encode
и decode
со строками в надежде удалить ужасную UnicodeDecodeError
- надеюсь, этот блог поможет вам преодолеть страх борьбы со струнами.Ниже я собираюсь использовать формат вопросов и ответов, чтобы действительно получить ответы на вопросы, которые могут у вас возникнуть, и которые у меня были до того, как я начал изучать строки.
1. Из чего сделаны струны?
В Python (2 или 3) строки могут быть представлены в байтах или кодовых точках Unicode .
Байт - это единица информации, состоящая из 8 бит - байты используются для хранения всех файлов на жестком диске. Таким образом, все файлы CSV и JSON на вашем компьютере состоят из байтов.Мы все можем согласиться с тем, что нам нужны байты, но как насчет кодовых точек Unicode?
Мы вернемся к ним в следующем вопросе.
2. Что такое Unicode и кодовые точки Unicode?
При чтении байтов из файла читателю необходимо знать, что означают эти байты. Поэтому, если вы напишете файл JSON и отправите его своему другу, вашему другу нужно будет знать, как обращаться с байтами в вашем файле JSON. В течение первых 20 лет компьютерных технологий заглавных и строчных букв английского алфавита, некоторых знаков препинания и цифр было достаточно.Все они были закодированы в список из 127 символов под названием ASCII. 7 бит информации или 1 байт достаточно для кодирования каждого английского символа. Вы можете сказать своему другу декодировать ваш файл JSON в кодировке ASCII, и вуаля - она сможет прочитать то, что вы ей отправили.
Это было круто в течение первых нескольких десятилетий или около того, но постепенно мы поняли, что существует гораздо большее количество символов, чем просто английские символы. Мы попытались расширить 127 символов до 256 символов (через Latin-1 или ISO-8859–1), чтобы полностью использовать 8-битное пространство, но этого было недостаточно.Нам нужен был международный стандарт, который, как мы все согласовали, имел дело с сотнями и тысячами неанглийских символов.
Пришел Unicode!
Unicode - это международный стандарт , в котором поддерживается отображение отдельных символов и уникального номера. По состоянию на май 2019 года самой последней версией Unicode является 12.1, которая содержит более 137 тысяч символов, включая различные сценарии, включая английский, хинди, китайский и японский языки, а также смайлики. Каждый из этих 137 тыс. Символов представлен точкой кода Юникода .Таким образом, кодовые точки Unicode относятся к фактическим отображаемым символам.
Эти кодовые точки кодируются в байты и декодируются из байтов обратно в кодовые точки. Примеры: кодовая точка Unicode для алфавита ,
- это U + 0061, эмодзи 🖐 - это U + 1F590, а для Ω - U + 03A9.
Три самых популярных стандарта кодирования, определенных Unicode, - это UTF-8, UTF-16 и UTF-32.
3. Что такое кодировки Unicode UTF-8, UTF-16 и UTF-32?
Теперь мы знаем, что Unicode - это международный стандарт, который кодирует каждый известный символ в уникальный номер.Тогда возникает следующий вопрос: как перемещать эти уникальные числа в Интернете? Вы уже знаете ответ! Использование байтов информации.
UTF-8: Он использует 1, 2, 3 или 4 байта для кодирования каждой кодовой точки. Он обратно совместим с ASCII. Всем английским символам нужен всего 1 байт, что довольно эффективно. Нам нужно больше байтов, только если мы отправляем неанглийские символы.
Это самая популярная форма кодирования, которая по умолчанию является кодировкой в Python 3.В Python 2 кодировка по умолчанию - ASCII (к сожалению).
UTF-16 - переменная 2 или 4 байт. Эта кодировка отлично подходит для азиатского текста, поскольку большая часть его может быть закодирована двумя байтами каждый. Это плохо для английского языка, так как для всех английских символов здесь тоже нужно 2 байта.
UTF-32 фиксированный 4 байт. Все символы закодированы в 4 байта, поэтому требуется много памяти. Используется не очень часто.
[Вы можете прочитать больше в этом сообщении StackOverflow.]
Нам нужен метод encode
для преобразования кодовых точек Unicode в байты. Обычно это происходит во время записи строковых данных, например, в файл CSV или JSON.
Нам нужен метод decode
для преобразования байтов в кодовые точки Unicode. Обычно это происходит при чтении данных из файла в строки.
4. Какие типы данных в Python обрабатывают кодовые точки и байты Unicode?
Как мы обсуждали ранее, в Python строки могут быть представлены либо в байтах, либо в кодовых точках Unicode.
Основные выводы в Python:
1. Python 2 использует тип str
для хранения байтов и тип unicode
для хранения кодовых точек Unicode. По умолчанию все строки имеют тип str
- байты ~ И кодировка по умолчанию - ASCII. Поэтому, если входящий файл состоит из кириллических символов, Python 2 может выйти из строя, потому что ASCII не сможет обрабатывать эти кириллические символы. В этом случае нам нужно не забыть использовать decode ("utf-8")
во время чтения файлов.Это неудобно.
2. Пришел Python 3 и исправил это. По умолчанию строки по-прежнему имеют тип str
, но теперь они означают кодовые точки Unicode - мы переносим то, что видим. Если мы хотим сохранить эти строки типа str
в файлах, мы вместо этого используем тип байт
. Кодировка по умолчанию - UTF-8 вместо ASCII. Идеально!
5. Есть ли примеры кода для сравнения различных типов данных?
Да, давайте посмотрим на «你好», что означает «привет» по-китайски.Для хранения этой строки, состоящей из двух кодовых точек Юникода, требуется 6 байтов. Давайте возьмем пример популярной функции len
, чтобы увидеть, как вещи могут отличаться в Python 2 и 3 - и что вам нужно помнить.
>>> print (len («你好»)) # Python 2 - str - это байты
6 >>> print (len (u «你好»)) # Python 2 - добавить 'u' для кодовых точек Unicode
2 >>> print (len («你好»)) # Python 3 - str - это кодовые точки Unicode
2
Итак, префикс u
в Python 2 может полностью изменить правильность работы вашего кода. - что может сбивать с толку! Python 3 исправил это, используя кодовые точки Unicode по умолчанию - поэтому len
будет работать так, как вы ожидали, давая длину 2 в приведенном выше примере.
Давайте рассмотрим другие примеры работы со строками в Python 3:
# строки по умолчанию состоят из кодовых точек Unicode
>>> print (len («你好»))
2 # Ручное кодирование строки в байты
>>> print (len (("你好") .encode ("utf-8")))
6 # Вам не нужно передавать аргумент, поскольку кодировка по умолчанию - "utf-8"
>>> print (len (("你好") .encode ()))
6 # Вывести фактические кодовые точки Unicode вместо символов [Источник]
>>> print (("你好").encode ("unicode_escape"))
b '\\ u4f60 \\ u597d' # Распечатать байты в кодировке UTF-8 для этой строки
>>> print (("你好") .encode ())
b '\ xe4 \ xbd \ xa0 \ xe5 \ xa5 \ xbd '
6. Информации много! Можете резюмировать?
Конечно! Давайте посмотрим визуально все, что мы рассмотрели до сих пор.
По умолчанию в Python 3 мы находимся слева в мире кодовых точек Unicode для строк. Нам нужно только перемещаться с байтами вперед и назад во время записи или чтения данных. Кодировка по умолчанию во время этого преобразования - UTF-8, но также могут использоваться другие кодировки.Нам нужно знать, какой кодировщик использовался в процессе декодирования, иначе мы можем получить ошибки или получить тарабарщину!
Эта диаграмма верна как для Python 2, так и для Python 3! Мы можем получить UnicodeDecodeErrors
из-за:
1) Мы пытаемся использовать ASCII для кодирования не-ASCII символов. Это случилось бы особенно. в Python 2, где кодировщиком по умолчанию является ASCII. Поэтому вы должны явно кодировать и декодировать байты с помощью UTF-8.
2) Возможно, мы полностью использовали неправильный декодер.Если кодовые точки Unicode были закодированы в UTF-16 вместо UTF-8, вы могли бы столкнуться с байтами, которые являются тарабарщиной в области UTF-8. Таким образом, декодер UTF-8 может полностью не понимать байты.
Хорошей практикой является декодирование ваших байтов в UTF-8 (или кодировщике, который использовался для создания этих байтов), как только они загружаются из файла. Запустите обработку в кодовых точках Unicode через свой код Python, а затем запишите обратно в байты в файл, используя кодировщик UTF-8 в конце. Это называется Unicode Sandwich.Прочтите / посмотрите отличный доклад Неда Батчелдера (@nedbat) об этом.
Если вы хотите добавить дополнительную информацию о строках в Python, укажите в комментариях ниже, так как это поможет другим. На этом мой блог о руководстве по Unicode, UTF-8 и строкам завершается. Удачи в ваших исследованиях с текстом!
PS, посмотрите мой новый подкаст! Это называется «Подкаст Data Life», где я говорю на похожие темы. В недавнем выпуске я говорил о том, почему Pandas - это новый Excel.Вы можете послушать подкаст здесь или где бы вы ни слушали свои подкасты.
Мой подкаст: The Data Life PodcastЕсли у вас есть какие-либо вопросы, напишите мне в моем профиле LinkedIn. Спасибо за прочтение!
encodeURIComponent () - JavaScript | MDN
Функция encodeURIComponent ()
кодирует
URI путем замены каждого экземпляра определенных символов одним, двумя, тремя,
или четыре escape-последовательности, представляющие кодировку UTF-8
символ (будет только четыре escape-последовательности для символов, состоящих из двух "суррогатных"
символы).
encodeURIComponent (uriComponent);
Параметры
-
uriComponent
Строка, число, логическое, пустое, неопределенное или любой объект. Перед кодированием
uriComponent
преобразуется в строку.
Возвращаемое значение
Новая строка, представляющая предоставленный uriComponent , закодированный как компонент URI.
encodeURIComponent ()
экранирует все символы , кроме :
Не сбежал: А-Я а-я 0-9 - _.! ~ * '()
encodeURIComponent ()
отличается от encodeURI
следующее:
var set1 = ";, /?: @ & = + $";
var set2 = "-_.! ~ * '()";
var set3 = "#";
var set4 = "ABC abc 123";
console.log (encodeURI (set1));
console.log (encodeURI (set2));
console.log (encodeURI (set3));
console.log (encodeURI (set4));
console.log (encodeURIComponent (set1));
console.log (encodeURIComponent (set2));
console.log (encodeURIComponent (set3));
консоль.журнал (encodeURIComponent (set4));
Обратите внимание, что URIError
будет выдан, если кто-то попытается закодировать суррогат.
который не является частью пары high-low, например,
console.log (encodeURIComponent ('\ uD800 \ uDFFF'));
console.log (encodeURIComponent ('\ uD800'));
console.log (encodeURIComponent ('\ uDFFF'));
Используйте encodeURIComponent ()
для полей, вводимых пользователем из форм POST
д к серверу. Это закодирует символы и
, которые
могут быть непреднамеренно сгенерированы во время ввода данных для специальных объектов HTML или других
символы, требующие кодирования / декодирования.
Например, если пользователь пишет Jack & Jill
, текст может быть закодирован как Jack & amp; Джилл
. Без encodeURIComponent ()
амперсанд может интерпретироваться на сервере как начало нового поля и подвергать опасности
целостность данных.
Для application / x-www-form-urlencoded
, пробелы должны быть заменены на +
, поэтому можно выполнить замену encodeURIComponent ()
с дополнительной заменой % 20
на +
.
Чтобы быть более строгим в соответствии с RFC 3986 (который оставляет за собой право!, ', (,), и *), хотя эти символы не имеют формализованного использования в качестве разделителей URI, можно безопасно использовать следующее:
function fixedEncodeURIComponent (str) {
return encodeURIComponent (str) .replace (/ [! '() *] / g, function (c) {
вернуть '%' + c.charCodeAt (0) .toString (16);
});
}
Кодирование заголовков Content-Disposition и Link
В следующем примере представлена специальная кодировка, необходимая для UTF-8. Content-Disposition
и Link
заголовок ответа сервера
параметры (например,g., имена файлов UTF-8):
var fileName = 'мой файл (2) .txt';
var header = "Content-Disposition: attachment; filename * = UTF-8 ''"
+ encodeRFC5987ValueChars (имя_файла);
console.log (заголовок);
function encodeRFC5987ValueChars (str) {
вернуть encodeURIComponent (str).
replace (/ ['()] / g, escape).
заменить (/ \ * / g, '% 2A').
replace (/% (?: 7C | 60 | 5E) / g, unescape);
}
function encodeRFC5987ValueChars2 (str) {
вернуть encodeURIComponent (str).replace (/ ['() *] / g, c => "%" + c.charCodeAt (0) .toString (16)).
replace (/% (7C | 60 | 5E) / g, (str, hex) => String.fromCharCode (parseInt (hex, 16)));
}
Таблицы BCD загружаются только в браузере
Как решить проблемы с кодировкой Unicode
Кодировкапрозрачна для большинства пользователей.
Он даже стал настолько прозрачным с момента рождения гениального формата Unicode UTF-8, что даже разработчик может потеряться в случае несовместимости.
РЕЗЮМЕ
1. Что такое кодирование?
⇒ Расшифровка кодировок на конкретном примере
2. Формат UTF-8
⇒ Сосредоточьтесь на формате Unicode UTF-8, который теоретически устраняет любые проблемы с кодировкой
3. Постоянные проблемы с кодировкой
⇒ Почему, несмотря на формат Unicode, проблемы с кодировкой остаются актуальными?
4. Определение кодировки файла
⇒ Мы предлагаем стандартные инструменты для простого определения кодировки текста
5.Расширенное упражнение VBA
⇒ Способ создания файлов Unicode в VBA с или без спецификации
Не стесняйтесь оставлять комментарии и запросы о поддержке по конкретной проблеме с кодировкой.
Строка хранится в памяти не как строка, а как 0 и 1 в двоичном формате.
Для нас наиболее читаемым представлением этого двоичного кода является шестнадцатеричный код, в котором каждый байт представляет отдельный символ в ASCII или в расширенном ASCII.
Пример :
Следующая строка закодирована кодом «Windows-1252»:
«L’exp é rience est le nom que chacun donne à ses erreurs.”Оскар Уайльд
В шестнадцатеричном коде это представлено, как показано ниже:
22 4C 27 65 78 70 E9 72 69 65 6E 63 65 20 65 73 | “L’exp é rience es |
74 20 6C 65 20 6E 6F 6D 20 71 75 65 20 63 68 61 | t le nom que cha |
63 75 6E 20 64 6F 6E 6E 65 20 E0 20 73 65 73 20 | cun donne à ses |
65 72 72 65 75 72 73 2E 22 20 4F 73 63 61 72 20 | ошибок.”Оскар |
57 69 6C 64 65 | Уайлд |
Седьмой символ « é » сохраняется в памяти с использованием следующего шестнадцатеричного значения: « E9 ».
В таблице символов Windows-1252 код « E9 » соответствует французскому символу « é »:
Окна-1252 (CP1252) | ||||||||||||||||
x0 | х1 | x2 | x3 | x4 | x5 | x6 | x7 | х8 | x9 | xA | xB | xC | xD | xE | xF | |
0x | NUL | SOH | STX | ETX | EOT | ENQ | ACK | BEL | BS | HT | LF | VT | FF | CR | SO | SI |
1x | DLE | DC1 | DC2 | DC3 | DC4 | НАК | SYN | ETB | CAN | EM | ПОД | ESC | FS | GS | RS | США |
2x | SP | ! | “ | # | $ | % | и | ‘ | ( | ) | * | + | , | – | . | _ |
6x | ` | a | б | c | г | e | f | г | ч | i | j | к | л | м | n | или |
7x | с. | q | r | с | т | u | v | Вт | х | л | z | { | | | } | ~ | DEL |
8x | € | ‚ | ƒ | „ | … | † | ‡ | ˆ | ‰ | Š | ‹ | Œ | Ž | |||
9x | ‘ | ‘ | “ | ” | • | – | – | ˜ | ™ | š | › | œ | ž | Ÿ | ||
Топор | НБСП | ¡ | ¢ | £ | ¤ | ¥ | ¦ | § | ¨ | © | ª | « | ¬ | ® | ¯ | |
Bx | ° | ± | ² | ³ | ´ | µ | ¶ | · | ¸ | ¹ | º | » | ¼ | ½ | ¾ | ¿ |
Сх | À | Á | Â | Ã | Ä | Å | Æ | Ç | È | É | Ê | Ë | Ì | Í | Î | Ï |
Dx | Ð | Ñ | Ò | Ó | Ô | Õ | Ö | × | Ø | Ù | Ú | Û | Ü | Ý | Þ | ß |
Пример: | до | á | â | ã | ä | å | æ | ç | и | é | ê | ë | ì | í | – | мк |
Fx | ð | - | х | - | ô | х | ö | ÷ | ø | ù | ú | û | ü | ý | þ | ÿ |
Тем не менее, если вы войдете в окно MS-DOS, шестнадцатеричный код «E9» не будет отображаться правильно!
Действительно, французское окно MS-DOS покажет следующее:
Cd \ temp
Типовые испытания.txt
«L’exp Ú rience est le nom que chacun donne Ó ses erreurs». Оскар Уайльд
Это просто потому, что MS-DOS по умолчанию считает, что тексты (на французском компьютере) кодируются с использованием страницы 850 ниже:
стр. 850 (DOS latin-1) | ||||||||||||||||
x0 | х1 | x2 | x3 | x4 | x5 | x6 | x7 | х8 | x9 | xA | xB | xC | xD | xE | xF | |
0x | NUL | SOH | STX | ETX | EOT | ENQ | ACK | BEL | BS | HT | LF | VT | FF | CR | SO | SI |
1x | DLE | DC1 | DC2 | DC3 | DC4 | НАК | SYN | ETB | CAN | EM | ПОД | ESC | FS | GS | RS | США |
2x | SP | ! | “ | # | $ | % | и | ‘ | ( | ) | * | + | , | – | . | _ |
6x | ` | a | б | c | г | e | f | г | ч | i | j | к | л | м | n | или |
7x | с. | q | r | с | т | u | v | Вт | х | л | z | { | | | } | ~ | DEL |
8x | Ç | ü | é | â | ä | до | å | ç | ê | ë | и | мк | – | ì | Ä | Å |
9x | É | æ | Æ | ô | ö | х | û | ù | ÿ | Ö | Ü | ø | £ | Ø | × | ƒ |
Топор | á | í | - | ú | - | Ñ | ª | º | ¿ | ® | ¬ | ½ | ¼ | ¡ | « | » |
Bx | ░ | ▒ | ▓ | │ | ┤ | Á | Â | À | © | ╣ | ║ | ╗ | ╝ | ¢ | ¥ | ┐ |
Сх | └ | ┴ | ┬ | ├ | ─ | ┼ | ã | Ã | ╚ | ╔ | ╩ | ╦ | ╠ | = | ╬ | ¤ |
Dx | ð | Ð | Ê | Ë | È | № | Í | Î | Ï | ┘ | ┌ | █ | ▄ | ¦ | Ì | ▀ |
Пример. | Ó | ß | Ô | Ò | х | Õ | µ | þ | Þ | Ú | Û | Ù | ý | Ý | ¯ | ´ |
Fx | SHY | ± | ‗ | ¾ | ¶ | § | ÷ | ¸ | ° | ¨ | · | ¹ | ³ | ² | ■ | НБСП |
Шестнадцатеричный код « E9 » соответствует символу « Ú » из списка символов на странице 850 и не соответствует символу « é », как мы могли ожидать.
Таким образом, понятно, что текстовый файл на самом деле является закодированным сообщением (не зашифрованным сообщением), которое следует декодировать с использованием точной таблицы перевода.
Таким образом, сложность двоякая:
- Вы должны тщательно выбирать, в зависимости от целевого приложения, кодировку для использования при сохранении текста.
- Когда пришло время отображать текст, необходимо определить используемую кодировку.
В блоге INVIVOO используется кодировка UTF-8. Но если бы вам было интересно принудительно использовать кодировку ISO-8859-7 в Internet Explorer с помощью меню «Вид => Кодировка => Больше => Греческий (ISO)», то следующие символы windows-1252 будут отображаться неправильно.
x0 | х1 | x2 | x3 | x4 | x5 | x6 | x7 | х8 | x9 | xA | xB | xC | xD | xE | xF | |
Fx | ð | - | х | - | ô | х | ö | ÷ | ø | ù | ú | û | ü | ý | þ | ÿ |
При использовании ISO-8859-7 указанные выше символы будут отображаться как следующие символы:
x0 | х1 | x2 | x3 | x4 | x5 | x6 | x7 | х8 | x9 | xA | xB | xC | xD | xE | xF | |
Fx | Γ ° | Γ ± | Γ² | Γ³ | Γ΄ | Γ΅ | ΓΆ | Г · | ΓΈ | ΓΉ | ΓΊ | Γ » | ΓΌ | Γ½ | ΓΎ | ΓΏ |
Мы видим, что ожидаемые западные символы теперь отображаются плохо и что есть 2 символа вместо одного.
Это связано с тем, что в кодировке Unicode UTF-8 все западные специальные символы имеют двухбайтовую кодировку . И потому, что кодировка ISO-8859-7 (греческий) считает, что каждый из этих двух байтов сам по себе является символом в своей таблице сопоставления.
Обратите внимание, что количество существующих кодировок довольно велико. У каждого из них есть веская причина быть, если вы знаете историю кодирования. После интернационализации, последовавшей за развитием Интернета, управление кодированием становилось все более и более сложным из-за многоязычных сред.
К счастью, , стандарт Unicode успешно справился с задачей собрать все символы из каждой кодировки в одну-единственную таблицу символов: список символов Unicode.
Формат Unicode родился из желания унифицировать множество существующих кодировок. Множественность кодов была необходима, потому что системы всегда считали, что один байт соответствует одному символу. Однако в байте можно закодировать только 256 символов.Поэтому некоторым языкам требовался собственный расширенный код ASCII. Французское « é », например, совершенно бесполезно для греков, которым также нужно кодировать целый собственный алфавит.
Решение Unicode состоит в том, чтобы избавиться от ограничения одного байта, чтобы иметь почти бесконечное количество возможных символов. Азиатские символы могут быть закодированы, например, с использованием 4 байтов.
К сожалению, существует несколько версий формата Unicode в зависимости от того, является ли количество байтов на символ фиксированным или динамическим, а также в зависимости от порядка чтения байтов.
Мы представим только формат UTF-8, потому что он имеет тенденцию доминировать из-за его эффективности с точки зрения размера памяти и из-за его обратной совместимости с ASCII. Действительно, ничто не отличает старый файл ASCII от файла UTF-8. Только при использовании специальных символов файл UTF-8 будет отличаться от ASCII.
Специальные символы в UTF-8 хранятся в шестнадцатеричном формате от 2 до 4 байтов. Он кодируется просто с учетом карты символов UTF-8. Почему-то все так же просто, как раньше. : «Код» всегда представляет собой отдельный символ в отображении символов.
Если приложение не может прочитать UTF-8 или если оно принудительно используется в расширенном ASCII (как в нашем предыдущем примере с принудительным использованием ISO-8859-7 в Internet Explorer), то приложение будет читать каждый байт как один отдельный символ. Однако все специальные символы Западной Европы закодированы 2 байтами в UTF-8.
=> Именно по этой причине подчеркнутые символы отображаются на двух символах вместо одного, когда кодировка определена неправильно.
Теперь вы знаете почти все о UTF-8:
- Имеет обратную совместимость с ASCII
- Специальные символы хранятся в 2–4 байтах
- Как и любая кодировка, приложение, которое «считывает» шестнадцатеричный код, должно использовать правильную кодировку
Вы знаете только «почти все», потому что в Unicode есть особая функция, которая по-прежнему вызывает некоторые проблемы совместимости: BOM (Byte Mark Order).Об этом мы поговорим в следующей части.
После этого необходимого представления кодировки текста мы, наконец, переходим к основной теме этой статьи, задав следующий вопрос:
Если UTF-8 содержит все символы и может заменить все коды, почему мы все еще сталкиваемся с проблемами кодирования ???
1. Изменение требует времени
Основная причина в том, что старые системы не обязательно развивались одновременно с революцией Unicode. Таким образом, могут быть некоторые базы данных, приложения или пакеты, которые могли быть запрограммированы на получение определенной кодировки, и достаточно часто они могли ожидать одного байта на символ.
2. Специфика Microsoft Windows
Microsoft взяла на себя смелость создать свои собственные таблицы символов, производные от таблиц ISO-8859-x. Более того, невозможно узнать, использует ли текст таблицу ISO или таблицу Windows, потому что обе они соответствуют просто последовательности байтов.
Эта свобода, полученная Microsoft, была бы меньшей проблемой, если бы приложения Windows использовали UTF-8 по умолчанию, но это не так. Пока нет специальных символов за пределами таблицы Windows-1252, большинство приложений Windows не кодируют тексты с использованием UTF-8.
Таким образом, отправка текстового файла Windows на сервер Linux или собственное приложение может легко ввести в заблуждение.
3. Символьные шрифты
Поскольку Unicode может кодировать все возможные символы, он стал кошмаром для художников, создающих шрифты, потому что перерисовка каждого символа - огромная задача. И они делают это не для того, чтобы сосредоточиться на интересующем их языке. Кроме того, стандарт Unicode может добавлять новые символы в таблицу, а существующие шрифты становятся неполными!
В результате для экзотических языков может потребоваться работа с определенными шрифтами.
Однако шрифты влияют только на отображение конечных пользователей и никоим образом не нарушают обработку или хранение строк в базе данных.
3. Спецификация (метка порядка байтов)
Знак порядка байтов представляет собой последовательность непечатаемых байтов Unicode, помещенных в начало текста Unicode для облегчения его интерпретации. Этот знак порядка байтов не является ни стандартным, ни обязательным, но он упрощает совместимым приложениям определение подтипа формата Unicode и направление чтения байтов.
Это часто вызывает проблемы совместимости, потому что не все приложения знают, как обрабатывать «BOM». Для несовместимых приложений эта последовательность байтов считается некоторыми нормальными символами в расширенном ASCII. В случае, если файл UTF-8 ошибочно распознан как файл Windows-1252, мы увидим 3 странных символа в самом начале файла: ï »¿.
Символы ï »¿соответствуют шестнадцатеричной строке EF BB BF, которая представляет собой код, указывающий совместимым приложениям, что файл является файлом Unicode в формате UTF-8.
Другая проблема спецификации - путаница, которую она может вызвать у пользователя. EF BB BF соответствует некоторым непечатаемым символам в UTF-8. Таким образом, в текстовом редакторе Unicode трудно узнать, была ли применена спецификация или нет, поскольку она невидима и необязательна в файле UTF-8. Многие пользователи, скорее всего, не знают, что такое BOM и как это может привести к сбою несовместимых приложений.
Есть несколько дополнительных спецификаций, которые можно использовать для обозначения форматов Unicode, отличающихся от UTF-8 и общих элементов, которые могут быть совместимы.
Поскольку спецификация невидима для пользователя, путаница очевидна и неизбежна.
Однако , в разделе ниже, мы предоставим вам стандартные инструменты, чтобы вы могли быстро определить, является ли ваш файл таким, каким вы его ожидаете.
Независимо от происхождения файла, сгенерированного автоматически, отправленного поставщиком данных или созданного вручную, может быть полезно проверить с абсолютной уверенностью его формат и показать возможную спецификацию тегов.
Если у вас нет доступа к расширенным (и обычно платным) текстовым редакторам, вы можете легко сделать это с помощью стандартных шестнадцатеричных редакторов в Windows и Linux.
В Windows:
- Ключевые окна + R
- Командная оболочка powershell
- Cd \ temp
- Fhx test.txt
В Linux:
cd / home / test /
file -bi test.txt
=> Linux «попытается» показать формат файла, но если вы хотите увидеть тег спецификации, необходимо ввести следующее :
xxd test.txt
Если в самом начале файла есть тег спецификации, то это текст в формате Unicode:
UTF-8 = EF BB BF
UTF-16 Big Endian = FE FF
UTF-16 Little Endian = FF FE
UTF-32 Big Endian = 00 00 FE FF
UTF-32 Little Endian = FF FE 00 00
Прежде всего, помните, что отсутствие тега спецификации не означает, что файл не является файлом Unicode.
Действительно, наоборот, может потребоваться его удаление для увеличения совместимости с вашими приложениями.
В следующей части мы увидим, как удалить спецификацию в VBA, чтобы избежать сбоев последующих приложений.
При создании файла Unicode с использованием макросов VBA, предназначенных для чувствительных к формату приложений, вы, вероятно, столкнетесь с некоторыми трудностями при освоении спецификации.
Для начала вы можете использовать команды, предложенные в предыдущем разделе, для проверки ваших выходных файлов.
Чтобы создавать файлы UTF-8 в удобное для вас время - с отметкой порядка байтов или без нее - вам необходимо знать следующие ограничения VBA :
1. Команда Print # 1 не сохраняется в UTF-8, вы потеряете свои символы Unicode.
Пример :
Откройте «c: \ Temp \ test.txt» для вывода как # 1
Print # 1, « Линия 1: особый символ Юникода: Ж = D0 96 ”
2. Команда SavetoFile из объекта «ADODB.Stream» всегда создает спецификацию «EF BB BF» для файлов UTF-8! Не ищите слишком много: нет возможности написать UTF-8 без спецификации, но мы предоставим вам решение .
Знание этих двух ограничений сэкономит вам много времени на исследования.
Ниже приведен пример кода, который позволяет создать два файла: один со спецификацией «EF BB BF», а другой - без спецификации.
Подложка Create_UTF8 ()
Dim lStreamUTF8BOM, lStreamBinaireSansBOM как объект
Установить lStreamUTF8BOM = CreateObject («ADODB.Stream»)
Установить lStreamBinaireSansBOM = CreateObject («ADODB.Stream»)
‘Мы создаем главный поток
lStreamUTF8BOM.Type = 2‘ 2 = Type Texte
lStreamUTF8BOM.Mode = 3 ‘3 = Mode Read and Write
lStreamUTF8BOM.Charset =« UTF-8 »‘ Unicode UTF-8 format with BOM
lStreamUTF8BOM.Open
lStreamUTF8BOM.WriteText «Линия 1: особый символ Юникода: Ж = D0 96» & vbCrLf
lStreamUTF8BOM.WriteText «Линия 2» & vbCrLf
‘сохранение как UTF-8 с BOM
lStreamUTF8BOM.SaveToFile« c: \ Temp \ UTF8withBOM.txt », 2‘ 2 = перезаписать
‘сохранение как UTF-8 без спецификации
lStreamBinaireSansBOM.Type = 1‘ 1 = двоичный поток
lStreamBinaireSansBOM.Mode = 3 ‘3 = Mode Read and Write
lStreamBinaireSansBOM.Open
lStreamUTF8BOM.Position = 3
lStreamUTF8BOM.CopyTo lStreamBinaireSansBOM
lStreamBinaireSansBOM.SaveToFile “c: \ Temp \ UTF8withoutBOM.txt”, 2 ‘2 = перезаписать
lStreamBinaireSansBOM.Flush
lStreamBinaireSansBOM.Close
lStream000.F8168 lStreamUT.F8163.Flush
Концевой переводник
Чтобы проверить результаты, вы можете открыть файлы в C: \ TEMP \ с помощью Powershell и команды fhx, как показано в предыдущем разделе.
Мы показали вам, как работает кодирование и что принесла революция UTF-8.
Однако несовместимость кодирования может сохраняться между приложениями, поэтому мы предложили вам несколько инструментов для проверки формата ваших файлов, а также для просмотра невидимой метки порядка байтов. Кроме того, теперь вы знаете, как создавать некоторые файлы UTF-8 с или без спецификации через VBA.
Теперь у вас есть все инструменты, которые помогут диагностировать возможные проблемы с кодировкой, и вы можете сделать это, используя только некоторые стандартные инструменты!
кодеков - Кодирование и декодирование строк
Назначение: | Кодировщики и декодеры для преобразования текста между различными представлениями. |
---|---|
Доступен в версии: | 2.1 и выше |
Модуль кодеков предоставляет потоковые и файловые интерфейсы для перекодирование данных в вашей программе. Чаще всего используется для работы с текстом Unicode, но другие кодировки также доступны для других целей.
Юникод Праймер
CPython 2.x поддерживает два типа строк для работы с текстовыми данными. Экземпляры str в старом стиле используют один 8-битный байт для представления каждый символ строки использует свой код ASCII.Наоборот, Строки Юникода управляются внутри как последовательность Кодовые точки Unicode . Значения кодовой точки сохраняются как последовательность размером 2 или 4 байта каждый, в зависимости от параметров, заданных, когда Python был составлен. И unicode, и str являются производными от общий базовый класс и поддерживает аналогичный API.
Когда выводятся строки Unicode, они кодируются с использованием одного нескольких стандартных схем, так что последовательность байтов может быть позже реконструируется как та же струна. Байты закодированного значение не обязательно совпадает со значениями кодовой точки, и кодирование определяет способ перевода между двумя наборами значений.Для чтения данных Unicode также необходимо знать кодировку, чтобы входящие байты могут быть преобразованы во внутреннее представление, используемое класс юникода.
Наиболее распространенными кодировками для западных языков являются UTF-8 и UTF-16, в котором используются последовательности из одно- и двухбайтовых значений. соответственно для представления каждого символа. Другие кодировки могут быть больше эффективен для хранения языков, где большинство символов представлены кодовыми точками, не умещающимися в два байта.
См. Также
Для получения дополнительной вводной информации о Unicode см. Список ссылок в конце этого раздела.Юникод Python HOWTO особенно полезно.
Кодировки
Лучший способ понять кодировки - это посмотреть на разные серия байтов, полученная путем кодирования одной и той же строки в разных способами. В приведенных ниже примерах эта функция используется для форматирования байтовой строки. чтобы было легче читать.
импорт binascii def to_hex (t, nbytes): «Форматировать текст t как последовательность значений длиной n байтов, разделенных пробелами». chars_per_item = nbytes * 2 hex_version = binascii.гекслифай (т) num_chunks = len (шестнадцатеричная_версия) / chars_per_item def chunkify (): для начала в xrange (0, len (hex_version), chars_per_item): yield hex_version [начало: начало + chars_per_item] возврат '' .join (chunkify ()) если __name__ == '__main__': печать to_hex ('abcdef', 1) печать to_hex ('abcdef', 2)
Функция использует binascii для получения шестнадцатеричного представления. входной байтовой строки, затем вставьте пробел между каждыми nbytes байтов перед возвратом значения.
$ python codecs_to_hex.py 61 62 63 64 65 66 6162 6364 6566
Первый пример кодировки начинается с печати текста 'pi: π' используя необработанное представление класса юникода. Π символ заменяется выражением для кодовой точки Unicode, \ u03c0. Следующие две строки кодируют строку как UTF-8 и UTF-16. соответственно, и показать шестнадцатеричные значения, полученные в результате кодирование.
из codecs_to_hex импортировать в_hex текст = u'pi: π ' print 'Raw:', repr (текст) напечатайте 'UTF-8:', to_hex (text.кодировать ('utf-8'), 1) напечатайте 'UTF-16:', to_hex (text.encode ('utf-16'), 2)
Результатом кодирования строки Unicode является str объект.
$ python codecs_encodings.py Raw: u'pi: \ u03c0 ' UTF-8: 70 69 3a 20 ср 80 UTF-16: fffe 7000 6900 3a00 2000 c003
Учитывая последовательность закодированных байтов как экземпляр str, decode () переводит их в кодовые точки и возвращает последовательность как экземпляр Unicode.
из codecs_to_hex импортировать в_hex текст = u'pi: π ' закодированный = текст.кодировать ('utf-8') декодированный = кодированный.decode ('utf-8') print 'Original:', repr (текст) print 'Encoded:', to_hex (закодировано, 1), тип (закодировано) print 'Decoded:', repr (декодировано), type (декодировано)
Выбор используемой кодировки не меняет тип вывода.
$ python codecs_decode.py Оригинал: u'pi: \ u03c0 ' Закодировано: 70 69 3a 20 cf 80Декодировано: u'pi: \ u03c0 '
Примечание
Кодировка по умолчанию устанавливается при запуске интерпретатора, когда сайт загружен.См. Параметры Unicode по умолчанию для описания настроек кодировки по умолчанию, доступных через sys.
Работа с файлами
Кодирование и декодирование строк особенно важно при работе с с операциями ввода-вывода. Независимо от того, пишете ли вы в файл, сокет или другой поток, вы захотите убедиться, что данные используют правильная кодировка. Как правило, все текстовые данные необходимо декодировать из его байтовое представление, как оно читается, и закодировано из внутреннего значения в конкретное представление, как это написано.Ваша программа может явно кодировать и декодировать данные, но в зависимости от кодировки использовать это может быть нетривиально, чтобы определить, достаточно ли вы прочитали байтов, чтобы полностью декодировать данные. кодеки обеспечивают классы, которые управляют кодированием и декодированием данных за вас, поэтому вы не обязательно создавать свои собственные.
Самый простой интерфейс, предоставляемый кодеками, заменяет встроенная функция open (). Новая версия работает так же, как встроенный, но добавляет два новых аргумента для указания кодировки и желаемый метод обработки ошибок.
из codecs_to_hex импортировать в_hex импортировать кодеки import sys кодировка = sys.argv [1] имя файла = кодировка + '.txt' print 'Запись в', имя файла с codecs.open (filename, mode = 'wt', encoding = encoding) как f: f.write (u'pi: \ u03c0 ') # Определяем группировку байтов для использования в to_hex () nbytes = {'utf-8': 1, 'utf-16': 2, 'utf-32': 4, } .get (кодировка, 1) # Показать необработанные байты в файле print 'Содержимое файла:' с open (filename, mode = 'rt') как f: напечатать to_hex (f.read (), nbytes)
Начиная со строки Unicode с кодовой точкой для π, этот пример сохраняет текст в файл, используя кодировку, указанную в командная строка.
$ python codecs_open_write.py utf-8 Запись в utf-8.txt Содержимое файла: 70 69 3a 20 ср 80 $ python codecs_open_write.py utf-16 Запись в utf-16.txt Содержимое файла: fffe 7000 6900 3a00 2000 c003 $ python codecs_open_write.py utf-32 Запись в utf-32.txt Содержимое файла: fffe0000 70000000 600 3a000000 20000000 c0030000
Чтение данных с помощью open () несложно, с одной уловкой: вы должны знать кодировку заранее, чтобы настроить декодер правильно.Некоторые форматы данных, например XML, позволяют указать кодирование как часть файла, но обычно это зависит от приложения управлять. кодеки просто принимают кодировку в качестве аргумента и предполагает, что это правильно.
импортных кодеков import sys кодировка = sys.argv [1] имя файла = кодировка + '.txt' print 'Reading from', имя файла с codecs.open (filename, mode = 'rt', encoding = encoding) как f: печать repr (f.read ())
В этом примере считываются файлы, созданные предыдущей программой, и печатает представление полученного объекта Unicode в консоль.
$ python codecs_open_read.py utf-8 Чтение из utf-8.txt u'pi: \ u03c0 ' $ python codecs_open_read.py utf-16 Чтение из utf-16.txt u'pi: \ u03c0 ' $ python codecs_open_read.py utf-32 Чтение из utf-32.txt u'pi: \ u03c0 '
Порядок байтов
Многобайтовые кодировки, такие как UTF-16 и UTF-32, создают проблему, когда передача данных между различными компьютерными системами, либо путем копирование файла напрямую или по сети. Другой системы используют разный порядок байтов старшего и младшего порядка.Этот характеристика данных, известная как ее порядок байтов , зависит от такие факторы, как архитектура оборудования и выбор, сделанный разработчик операционной системы и приложений. Не всегда есть способ заранее знать, какой порядок байтов использовать для данного набора данных, поэтому многобайтовые кодировки включают маркер порядка байтов (BOM) в качестве первые несколько байтов закодированного вывода. Например, UTF-16 определяется таким образом, что 0xFFFE и 0xFEFF не являются допустимыми символами и могут использоваться для указания порядка байтов.кодеки определяют константы для маркеров порядка байтов, используемых UTF-16 и UTF-32.
импортных кодеков из codecs_to_hex импортировать в_hex для имени в ['BOM', 'BOM_BE', 'BOM_LE', 'BOM_UTF8', 'BOM_UTF16', 'BOM_UTF16_BE', 'BOM_UTF16_LE', 'BOM_UTF32', 'BOM_UTF32_BE', 'BOM_UTF32_LE', ]: print '{: 12}: {}'. format (имя, to_hex (getattr (кодеки, имя), 2))
BOM, BOM_UTF16 и BOM_UTF32 автоматически устанавливаются на подходящие значения с прямым или обратным порядком байтов в зависимости от собственный порядок байтов текущей системы.
$ python codecs_bom.py Спецификация: fffe BOM_BE: feff BOM_LE: fffe BOM_UTF8: efbb bf BOM_UTF16: fffe BOM_UTF16_BE: feff BOM_UTF16_LE: fffe BOM_UTF32: fffe 0000 BOM_UTF32_BE: 0000 feff BOM_UTF32_LE: fffe 0000
Порядок байтов обнаруживается и обрабатывается автоматически декодерами в кодеков, но вы также можете выбрать явный порядок для кодирование.
импортных кодеков из codecs_to_hex импортировать в_hex # Выберите неродную версию кодировки UTF-16 если кодеки.BOM_UTF16 == кодеки.BOM_UTF16_BE: bom = кодеки.BOM_UTF16_LE кодировка = 'utf_16_le' еще: bom = кодеки.BOM_UTF16_BE кодировка = 'utf_16_be' напечатать 'Собственный порядок:', to_hex (codecs.BOM_UTF16, 2) print 'Выбранный заказ:', to_hex (bom, 2) # Закодировать текст. encoded_text = u'pi: \ u03c0'.encode (кодировка) print '{: 14}: {}'. format (кодировка, to_hex (encoded_text, 2)) с open ('non-native-encoded.txt', mode = 'wb') как f: # Записать выбранный маркер порядка байтов. Он не входит в # закодированный текст, потому что мы явно указали порядок байтов, когда # выбор кодировки.е. писать (бом) # Записать байтовую строку для закодированного текста. f.write (кодированный_текст)
codecs_bom_create_file.py определяет собственный порядок байтов, затем явно использует альтернативную форму, поэтому следующий пример может демонстрировать автоопределение при чтении.
$ Python codecs_bom_create_file.py Собственный порядок: fffe Выбранный заказ: feff utf_16_be: 0070 0069 003a 0020 03c0
codecs_bom_detection.py не указывает порядок байтов при открытии файл, поэтому декодер использует значение спецификации в первых двух байтах файл, чтобы определить это.
импортных кодеков из codecs_to_hex импортировать в_hex # Посмотрите необработанные данные с open ('non-native-encoded.txt', mode = 'rb') как f: raw_bytes = f.read () напечатать 'Raw:', to_hex (raw_bytes, 2) # Снова откройте файл и позвольте кодекам определить спецификацию с codecs.open ('non-native-encoded.txt', mode = 'rt', encoding = 'utf-16') как f: decoded_text = f.read () print 'Decoded:', repr (decoded_text)
Поскольку первые два байта файла используются для порядка следования байтов обнаружения, они не включаются в данные, возвращаемые функцией read ().
$ python codecs_bom_detection.py Необработанный: feff 0070 0069 003a 0020 03c0 Декодировано: u'pi: \ u03c0 '
Обработка ошибок
В предыдущих разделах указывалось на необходимость знать, какая кодировка используется при чтении и записи файлов Unicode. Установка кодировки правильно важно по двум причинам. Если кодировка настроена некорректно при чтении из файла данные будут интерпретироваться неправильно и может быть поврежден или просто не может декодироваться. Не весь Юникод символы могут быть представлены во всех кодировках, поэтому при неправильном кодировка используется при записи будет сгенерирована ошибка, и данные могут Потерянный.
Кодекииспользуют те же пять опций обработки ошибок, что и обеспечивается методом unicode encode () и decode () для str.
Режим ошибки | Описание |
---|---|
строгий | Вызывает исключение, если данные не могут быть преобразованы. |
заменить | Заменяет специальный символ-маркер для данных, которые не могут быть закодированы. |
игнорировать | Пропускает данные. |
xmlcharrefreplace | Символ XML (только кодировка) |
обратная косая черта заменить | escape-последовательность (только кодирование) |
Ошибки кодирования
Самая распространенная ошибка - получение UnicodeEncodeError при записи Данные Unicode в выходной поток ASCII, например в обычный файл или sys.stdout . Эту программу-пример можно использовать поэкспериментировать с различными режимами обработки ошибок.
импортных кодеков import sys error_handling = sys.argv [1] текст = u'pi: \ u03c0 ' пытаться: # Сохраняем данные в кодировке ASCII, используя ошибку # режим обработки, указанный в командной строке. с codecs.open ('encode_error.txt', 'w', кодировка = 'ascii', errors = error_handling) как f: f.write (текст) кроме UnicodeEncodeError, ошибка: напечатайте 'ERROR:', err еще: # Если при записи в файл ошибок не было, # показать, что в нем содержится.с open ('encode_error.txt', 'rb') как f: print 'Содержимое файла:', repr (f.read ())
Хотя строгий режим является самым безопасным для обеспечения безопасности вашего приложения явно устанавливает правильную кодировку для всех операций ввода-вывода, он может привести к сбою программы при возникновении исключения.
$ python codecs_encode_error.py строгий ОШИБКА: кодек ascii не может кодировать символ u '\ u03c0' в позиции 4: порядковый номер не в диапазоне (128)
Некоторые другие режимы ошибок более гибкие.Например, replace гарантирует отсутствие ошибок за счет возможно потеря данных, которые не могут быть преобразованы в запрошенные кодирование. Символ Юникода для пи по-прежнему не может быть закодирован в ASCII, но вместо вызова исключения символ заменяется с участием ? на выходе.
$ python codecs_encode_error.py заменить Содержимое файла: 'pi:?'
Чтобы полностью пропустить данные о проблеме, используйте ignore. Любые данные, которые не может быть закодирован, просто отбрасывается.
$ python codecs_encode_error.py игнорировать Содержимое файла: 'pi:'
Есть два варианта обработки ошибок без потерь, оба из которых заменяют персонаж с альтернативным представлением, определенным стандартом отдельно от кодировки. xmlcharrefreplace использует XML ссылка на символ в качестве замены (список ссылок на символы указан в определениях сущностей XML W3C для символов).
$ python codecs_encode_error.py xmlcharrefreplace Содержимое файла: 'pi: & # 960;'
Другой схемой обработки ошибок без потерь является обратная косая черта. создает выходной формат, подобный значению, которое вы получаете при печати repr () объекта Unicode.Символы Юникода заменен на \ u, за которым следует шестнадцатеричное значение кода точка.
$ python codecs_encode_error.py обратная косая чертаreplace Содержимое файла: 'pi: \\ u03c0'
Ошибки декодирования
Также можно увидеть ошибки при декодировании данных, особенно если используется неправильная кодировка.
импортных кодеков import sys из codecs_to_hex импортировать в_hex error_handling = sys.argv [1] текст = u'pi: \ u03c0 ' print 'Original:', repr (текст) # Сохраняем данные в одной кодировке с кодеками.open ('decode_error.txt', 'w', encoding = 'utf-16') как f: f.write (текст) # Дамп байтов из файла с open ('decode_error.txt', 'rb') как f: print 'Содержимое файла:', to_hex (f.read (), 1) # Пытаться прочитать данные с неправильной кодировкой с codecs.open ('decode_error.txt', 'r', кодировка = 'utf-8', errors = error_handling) как f: пытаться: data = f.read () кроме UnicodeDecodeError, ошибка: напечатайте 'ERROR:', err еще: print 'Read:', repr (данные)
Как и в случае с кодированием, режим строгой обработки ошибок вызывает исключение. если поток байтов не может быть правильно декодирован.В этом случае UnicodeDecodeError результаты из пытается преобразовать часть спецификации UTF-16 в символ, используя Декодер UTF-8.
$ python codecs_decode_error.py строгий Оригинал: u'pi: \ u03c0 ' Содержимое файла: ff fe 70 00 69 00 3a 00 20 00 c0 03 ОШИБКА: кодек 'utf8' не может декодировать байт 0xff в позиции 0: недопустимый начальный байт
Переключение на игнорирование заставляет декодер пропускать недопустимые байтов. Однако результат все еще не совсем то, что ожидалось, поскольку он включает встроенные нулевые байты.
$ python codecs_decode_error.py игнорировать Оригинал: u'pi: \ u03c0 ' Содержимое файла: ff fe 70 00 69 00 3a 00 20 00 c0 03 Прочтите: u'p \ x00i \ x00: \ x00 \ x00 \ x03 '
В режиме замены недопустимые байты заменяются на \ uFFFD, официальный символ замены Unicode, который выглядит как ромб на черном фоне с белым вопросительным знаком (�).
$ python codecs_decode_error.py заменить Оригинал: u'pi: \ u03c0 ' Содержимое файла: ff fe 70 00 69 00 3a 00 20 00 c0 03 Прочтите: u '\ ufffd \ ufffdp \ x00i \ x00: \ x00 \ x00 \ ufffd \ x03'
Стандартные потоки ввода и вывода
Наиболее частой причиной исключения UnicodeEncodeError является код, который пытается распечатать данные Unicode в консоль или конвейер Unix, когда sys.stdout не настроен с кодирование.
импортных кодеков import sys текст = u'pi: π ' # Печать в стандартный вывод может вызвать ошибку кодирования print 'Кодировка по умолчанию:', sys.stdout.encoding напечатайте 'TTY:', sys.stdout.isatty () печатать текст
Проблемы с кодировкой по умолчанию для стандартных каналов ввода / вывода могут быть трудно отлаживать, потому что программа работает должным образом, когда вывод идет на консоль, но вызывает ошибки кодирования при использовании как часть конвейера, и вывод включает символы Unicode, указанные выше диапазон ASCII.Это различие в поведении вызвано тем, что Python код инициализации, который устанавливает кодировку по умолчанию для каждого стандарта Канал ввода / вывода , только если канал подключен к терминалу (isatty () возвращает True). Если терминала нет, Python предполагает, что программа явно настроит кодировку, и оставляет только канал ввода / вывода.
$ python codecs_stdout.py Кодировка по умолчанию: utf-8 TTY: Верно пи: π $ python codecs_stdout.py | Кот - Кодировка по умолчанию: Нет Телетайп: ложь Отслеживание (последний вызов последний): Файл "codecs_stdout.py ", строка 18, впечатать текст UnicodeEncodeError: кодек ascii не может кодировать символ u '\ u03c0' в позиция 4: порядковый номер вне диапазона (128)
Чтобы явно установить кодировку для стандартного выходного канала, используйте getwriter (), чтобы получить класс кодировщика потока для определенного кодирование. Создайте экземпляр класса, передав sys.stdout как единственный аргумент.
импортных кодеков import sys текст = u'pi: π ' # Оберните sys.stdout писателем, который знает, как обрабатывать кодирование # Данные Unicode.wrapped_stdout = codecs.getwriter ('UTF-8') (sys.stdout) wrapped_stdout.write (u'Via write: '+ текст +' \ n ') # Заменить sys.stdout писателем sys.stdout = обернутый_stdout print u'Via print: ', текст
Запись в упакованную версию sys.stdout передает Unicode текст через кодировщик перед отправкой закодированных байтов на стандартный вывод. Замена sys.stdout означает, что любой код, используемый вашим приложением который печатает на стандартный вывод, сможет воспользоваться преимуществами кодирующий писатель.
$ python codecs_stdout_wrapped.ру Через запись: pi: π Через печать: pi: π
Следующая проблема, которую необходимо решить, - как узнать, какая кодировка должна быть использовал. Правильная кодировка зависит от местоположения, языка и пользовательская или системная конфигурация, поэтому жесткое кодирование фиксированного значения не является отличная идея. Также было бы неприятно, если бы пользователю пришлось пройти явные аргументы для каждой программы, устанавливающей ввод и вывод кодировки. К счастью, есть глобальный способ получить разумную кодировка по умолчанию с использованием локали.
импортных кодеков импортировать локаль import sys текст = u'pi: π ' # Настроить языковой стандарт в настройках среды пользователя.locale.setlocale (locale.LC_ALL, '') # Обернуть stdout писателем с поддержкой кодировки. язык, кодировка = locale.getdefaultlocale () print 'Кодировка локали:', кодировка sys.stdout = codecs.getwriter (кодировка) (sys.stdout) print 'С обернутым стандартным выводом:', текст
getdefaultlocale () возвращает язык и предпочтительную кодировку. на основе параметров конфигурации системы и пользователя в форме, которая может использоваться с getwriter ().
$ python codecs_stdout_locale.py Кодировка локали: UTF-8 С обернутым stdout: pi: π
Кодировку также необходимо настроить при работе с sys.stdin . Используйте getreader (), чтобы читатель мог декодирование входных байтов.
импортных кодеков импортировать локаль import sys # Настроить языковой стандарт в настройках среды пользователя. locale.setlocale (locale.LC_ALL, '') # Обернуть stdin читателем с поддержкой кодировки. язык, кодировка = locale.getdefaultlocale () sys.stdin = codecs.getreader (кодировка) (sys.stdin) напечатать 'From stdin:', repr (sys.stdin.read ())
Чтение из обернутого дескриптора возвращает объекты Unicode вместо экземпляров str.
$ python codecs_stdout_locale.py | Python codecs_stdin.py Из stdin: u 'Локальная кодировка: UTF-8 \ nС упакованным stdout: pi: \ u03c0 \ n'
Сетевые коммуникации
Сетевые сокеты также являются байтовыми потоками, поэтому данные Unicode должны быть кодируется в байтах перед записью в сокет.
импортных систем импорт SocketServer класс Echo (SocketServer.BaseRequestHandler): def handle (self): # Получить несколько байтов и передать их клиенту. данные = себя.request.recv (1024) self.request.send (данные) возвращение если __name__ == '__main__': импортировать кодеки импортный сокет импорт потоковой передачи address = ('localhost', 0) # пусть ядро предоставит нам порт server = SocketServer.TCPServer (адрес, эхо) ip, port = server.server_address # узнаем, какой порт нам дали t = threading.Thread (цель = server.serve_forever) t.setDaemon (True) # не зависать при выходе t.start () # Подключиться к серверу s = socket.socket (socket.AF_INET, socket.SOCK_STREAM) s.connect ((ip, порт)) # Отправляем данные текст = u'pi: π ' len_sent = s.send (текст) # Получите ответ ответ = s.recv (len_sent) напечатать репор (ответ) # Очистить s.close () server.socket.close ()
Вы можете явно закодировать данные перед их отправкой, но пропустите один вызов send (), и ваша программа не сработает с кодировкой ошибка.
$ python codecs_socket_fail.py Отслеживание (последний вызов последний): Файл "codecs_socket_fail.py ", строка 43, вlen_sent = s.send (текст) UnicodeEncodeError: кодек ascii не может кодировать символ u '\ u03c0' в позиция 4: порядковый номер вне диапазона (128)
Используя makefile (), чтобы получить файловый дескриптор для сокета, а затем обернув его потоковым читателем или писателем, вы иметь возможность передавать строки Unicode и знать, что они закодированы в пути в розетку и из нее.
импортных систем импорт SocketServer класс Echo (SocketServer.BaseRequestHandler): def handle (self): # Получить несколько байтов и передать их клиенту.Там есть # их не нужно декодировать, так как они не используются. данные = self.request.recv (1024) self.request.send (данные) возвращение класс PassThrough (объект): def __init __ (себя, другое): self.other = другой def write (self, data): print 'Writing:', repr (данные) вернуть self.other.write (данные) def read (self, size = -1): print 'Reading:', data = self.other.read (размер) печать репр (данные) вернуть данные def flush (сам): вернуть себя.other.flush () def close (self): вернуть self.other.close () если __name__ == '__main__': импортировать кодеки импортный сокет импорт потоковой передачи address = ('localhost', 0) # пусть ядро предоставит нам порт server = SocketServer.TCPServer (адрес, эхо) ip, port = server.server_address # узнаем, какой порт нам дали t = threading.Thread (цель = server.serve_forever) t.setDaemon (True) # не зависать при выходе t.start () # Подключиться к серверу s = розетка.сокет (socket.AF_INET, socket.SOCK_STREAM) s.connect ((ip, порт)) # Оберните сокет ридером и писателем. input = codecs.getreader ('utf-8') (PassThrough (s.makefile ('r'))) исходящий = codecs.getwriter ('utf-8') (PassThrough (s.makefile ('w'))) # Отправляем данные текст = u'pi: π ' print 'Sending:', repr (текст) исходящий.write (текст) outgoing.flush () # Получите ответ response = incoming.read () print 'Received:', repr (ответ) # Очистить s.close () сервер.socket.close ()
В этом примере используется PassThrough, чтобы показать, что данные кодируется перед отправкой, а ответ декодируется после того, как он получил в клиенте.
$ python codecs_socket.py Отправка: u'pi: \ u03c0 ' Написание: 'pi: \ xcf \ x80' Чтение: 'pi: \ xcf \ x80' Получено: u'pi: \ u03c0 '
Кодирование перевода
Хотя большинство приложений будут работать с данными Unicode внутренне, декодируя или кодируя его как часть операции ввода-вывода, там бывают случаи, когда вы меняете кодировку файла, не придерживаясь этого промежуточный формат данных полезен.EncodedFile () открывает дескриптор файла с использованием одной кодировки и обертывает его классом, переводит данные в другую кодировку по мере того, как происходит ввод-вывод.
из codecs_to_hex импортировать в_hex импортировать кодеки из cStringIO импортировать StringIO # Необработанная версия исходных данных. данные = u'pi: \ u03c0 ' # Вручную закодируйте его как UTF-8. utf8 = data.encode ('utf-8') print 'Начать как UTF-8:', to_hex (utf8, 1) # Настроить выходной буфер, а затем обернуть его как EncodedFile. вывод = StringIO () encoded_file = кодеки.EncodedFile (вывод, data_encoding = 'utf-8', file_encoding = 'utf-16') encoded_file.write (utf8) # Получить содержимое буфера как байтовую строку в кодировке UTF-16 utf16 = output.getvalue () print 'Закодировано в UTF-16:', to_hex (utf16, 2) # Настроить другой буфер с данными UTF-16 для чтения, # и оберните его другим EncodedFile. буфер = StringIO (utf16) encoded_file = codecs.EncodedFile (буфер, data_encoding = 'utf-8', file_encoding = 'utf-16') # Прочитать версию данных в кодировке UTF-8.recoded = encoded_file.read () print 'Вернуться в UTF-8:', to_hex (перекодировано, 1)
В этом примере показано чтение и запись в отдельные дескрипторы. возвращается EncodedFile (). Независимо от того, используется ли ручка для чтения или записи file_encoding всегда относится к кодировка, используемая дескриптором открытого файла, переданным в качестве первого аргумента, и data_encoding Значение относится к кодировке, используемой данными проходя через вызовы read () и write ().
$ python codecs_encodedfile.ру Начать как UTF-8: 70 69 3a 20 cf 80 Закодировано в UTF-16: fffe 7000 6900 3a00 2000 c003 Вернуться к UTF-8: 70 69 3a 20 cf 80
Кодировки, отличные от Unicode
Хотя в большинстве предыдущих примеров используются кодировки Unicode, кодеки могут использоваться для многих других переводов данных. Для Например, Python включает кодеки для работы с base-64, bzip2, ROT-13, ZIP и другие форматы данных.
импортных кодеков из cStringIO импортировать StringIO буфер = StringIO () stream = codecs.getwriter ('rot_13') (буфер) текст = 'abcdefghijklmnopqrstuvwxyz' транслировать.написать (текст) stream.flush () печать 'Оригинал:', текст напечатайте 'ROT-13:', buffer.getvalue ()
Любое преобразование, которое может быть выражено как функция, принимающая один входной аргумент и возвращение байтовой или Unicode-строки может быть зарегистрирован как кодек.
$ python codecs_rot13.py Оригинал: abcdefghijklmnopqrstuvwxyz ROT-13: nopqrstuvwxyzabcdefghijklm
Использование кодеков для упаковки потока данных обеспечивает более простой интерфейс чем работать напрямую с zlib.
импортных кодеков из cStringIO импортировать StringIO из codecs_to_hex импортировать в_hex буфер = StringIO () поток = кодеки.getwriter ('zlib') (буфер) text = 'abcdefghijklmnopqrstuvwxyz \ n' * 50 stream.write (текст) stream.flush () print 'Исходная длина:', len (текст) compressed_data = buffer.getvalue () print 'ZIP сжат:', len (compressed_data) буфер = StringIO (сжатые_данные) stream = codecs.getreader ('zlib') (буфер) first_line = stream.readline () print 'Прочитать первую строку:', repr (first_line) uncompressed_data = первая_строка + stream.read () print 'Несжатый:', len (несжатые_данные) print 'Same:', text == uncompressed_data
Не все системы сжатия или кодирования поддерживают чтение часть данных через потоковый интерфейс, используя readline () или read (), потому что им нужно найти конец сжатый сегмент, чтобы расширить его.Если ваша программа не может удерживать весь несжатый набор данных в памяти, используйте инкрементный доступ возможности библиотеки сжатия вместо кодеков.
$ python codecs_zlib.py Длина оригинала: 1350 Сжатый ZIP: 48 Прочтите первую строку: 'abcdefghijklmnopqrstuvwxyz \ n' Без сжатия: 1350 То же: Верно
Инкрементное кодирование
Некоторые из представленных кодировок, особенно bz2 и zlib, могут кардинально меняют длину потока данных по мере того, как над ним работают.Для больших наборов данных эти кодировки лучше работают постепенно, работая с небольшими порциями данных за раз. В IncrementalEncoder и IncrementalDecoder API - это предназначен для этой цели.
импортных кодеков import sys из codecs_to_hex импортировать в_hex текст = 'abcdefghijklmnopqrstuvwxyz \ n' повторений = 50 print 'Длина текста:', len (текст) печать "Повторения:", повторения print 'Ожидаемая длина:', len (текст) * повторений # Кодировать текст несколько раз, накапливая большой объем данных кодировщик = кодеки.getincrementalencoder ('bz2') () encoded = [] Распечатать print 'Кодировка:', для i в диапазоне (повторения): en_c = encoder.encode (текст, финал = (i == повторы-1)) если en_c: print '\ nEncoded: {} bytes'.format (len (en_c)) encoded.append (en_c) еще: sys.stdout.write ('.') bytes = '' .join (закодировано) Распечатать print 'Общая закодированная длина:', len (байты) Распечатать # Декодировать байтовую строку по одному байту за раз декодер = codecs.getincrementaldecoder ('bz2') () декодировано = [] print 'Декодирование:', для i, b в перечислении (байты): final = (i + 1) == len (текст) c = декодер.декодировать (b, финал) если c: print '\ nDecoded: {} characters'.format (len (c)) print 'Декодирование:', decoded.append (c) еще: sys.stdout.write ('.') Распечатать восстановлено = u ''. join (декодировано) Распечатать print 'Общая длина без сжатия:', len (восстановлено)
Каждый раз, когда данные передаются в кодировщик или декодер, его внутреннее состояние обновлено. Когда состояние согласовано (как определено кодеком), данные возвращаются, и состояние сбрасывается. До этого момента звонки encode () или decode () не вернет никаких данных.Когда передается последний бит данных, аргумент final должен быть установлен в Верно, поэтому кодек знает, что нужно очистить все оставшиеся буферизованные данные.
$ python codecs_incremental_bz2.py Длина текста: 27 Повторений: 50 Ожидаемая длина: 1350 Кодировка: ................................................ . Закодировано: 99 байт Общая кодированная длина: 99 Расшифровка: ................................................ ............ ............................ Расшифровано: 1350 символов Расшифровка: .......... Общая длина без сжатия: 1350
Определение собственной кодировки
Поскольку Python уже поставляется с большим количеством стандартных кодеков, он вряд ли вам нужно будет определять свое собственное. Если да, то там несколько базовых классов в кодеках, чтобы упростить процесс.
Первый шаг - понять природу преобразования описывается кодировкой. Например, кодировка invertcaps преобразует прописные буквы в строчные, а строчные - в верхний регистр.Вот простое определение функции кодирования, которая выполняет это преобразование во входной строке:
строка импорта def invertcaps (текст): "" "Вернуть новую строку с измененным регистром всех букв. "" " return '' .join (c.upper (), если c в string.ascii_lowercase иначе c.lower (), если c в string.ascii_uppercase иначе c для c в тексте ) если __name__ == '__main__': напечатать invertcaps ('ABC.def') напечатать invertcaps ('abc.DEF ')
В этом случае кодер и декодер выполняют одну и ту же функцию (как с РОТ-13).
$ python codecs_invertcaps.py abc.DEF ABC.def
Хотя это легко понять, эта реализация не эффективен, особенно для очень больших текстовых строк. К счастью, кодеки включают несколько вспомогательных функций для создания символа кодеки на основе карты , такие как invertcaps. Кодировка карты символов состоит из двух словарей. Карта кодировки преобразует символы значения из входной строки в байтовые значения на выходе и Карта декодирования идет другим путем.Сначала создайте карту декодирования, а затем используйте make_encoding_map (), чтобы преобразовать его в кодировку карта. Функции C charmap_encode () и charmap_decode () использует карты для преобразования их входных данных эффективно.
импортных кодеков строка импорта # Сопоставьте каждый символ с собой decoding_map = codecs.make_identity_dict (диапазон (256)) # Составьте список пар порядковых значений для нижнего и верхнего регистра # письма pair = zip ([ord (c) вместо c в string.ascii_lowercase], [ord (c) вместо c в строке.ascii_uppercase]) # Измените отображение, чтобы преобразовать верхнее значение в нижнее и нижнее в верхнее. decoding_map.update (dict ((верхний, нижний) для (нижний, верхний) парами)) decoding_map.update (dict ((нижний, верхний) для (нижний, верхний) парами)) # Создать отдельную карту кодировки. encoding_map = codecs.make_encoding_map (decoding_map) если __name__ == '__main__': распечатать codecs.charmap_encode ('abc.DEF', 'strict', encoding_map) распечатать codecs.charmap_decode ('abc.DEF', 'strict', decoding_map) печать encoding_map == decoding_map
Хотя карты кодирования и декодирования для инвертированных колпачков одинаковы, это может быть не всегда.make_encoding_map () обнаруживает ситуации, когда более одного входного символа закодированы в один и тот же выходной байт и заменяет значение кодировки на None, чтобы отметить кодировка как неопределенная.
$ python codecs_invertcaps_charmap.py ('ABC.def', 7) (u'ABC.def ', 7) Правда
Кодировщик и декодер символьной карты поддерживают все стандартные методы обработки ошибок, описанные ранее, поэтому вам не нужно ничего делать дополнительная работа для соответствия этой части API.
импортных кодеков из codecs_invertcaps_charmap import encoding_map текст = u'pi: π ' для ошибки в ['игнорировать', 'заменить', 'строгий']: пытаться: закодированные = кодеки.charmap_encode (текст, ошибка, кодировка_карты) кроме UnicodeEncodeError, ошибка: закодировано = str (ошибка) print '{: 7}: {}'. format (ошибка, закодировано)
Поскольку кодовая точка Unicode для π отсутствует в карте кодирования, режим строгой обработки ошибок вызывает исключение.
$ python codecs_invertcaps_error.py игнорировать: ('PI:', 5) replace: ('PI:?', 5) строгий: кодек 'charmap' не может кодировать символ u '\ u03c0' в позиции 4: символы отображаются в <не определено>
После того, как определены карты кодирования и декодирования, необходимо установить создайте несколько дополнительных классов и зарегистрируйте кодировку.register () добавляет функцию поиска в реестр, чтобы при пользователь хочет использовать ваши кодеки кодирования, может найти его. В функция поиска должна принимать единственный строковый аргумент с именем кодировку и вернуть объект CodecInfo, если он знает кодировка или None, если это не так.
импортных кодеков импортные кодировки def search2 (кодировка): print 'search2: Поиск:', кодировка return None def search3 (кодировка): print 'search3: Поиск:', кодировка return None кодеки.зарегистрироваться (search2) codecs.register (search3) utf8 = codecs.lookup ('utf-8') напечатайте 'UTF-8:', utf8 пытаться: unknown = codecs.lookup ('без такой-кодировки') кроме LookupError, ошибка: напечатайте 'ERROR:', err
Вы можете зарегистрировать несколько функций поиска, и каждая будет вызываться в поворачивайте, пока один из них не вернет CodecInfo или пока список не будет исчерпан. Зарегистрированная кодеками функция внутреннего поиска знает, как загружать стандартные кодеки, такие как UTF-8, из кодировок, чтобы те имена никогда не будут переданы в вашу функцию поиска.
$ python codecs_register.py UTF-8: <объект codecs.CodecInfo для кодирования utf-8 в 0x100452ae0> search2: поиск: no-such-encoding search3: Поиск: no-such-encoding ОШИБКА: неизвестная кодировка: нет такой-кодировки
Экземпляр CodecInfo, возвращаемый функцией поиска, сообщает кодеков, как кодировать и декодировать, используя все различные поддерживаемые механизмы: без сохранения состояния, инкрементальные и потоковые. кодеки включают базовые классы, которые делают настройку персонажа кодирование карты легко.В этом примере все части собираются вместе, чтобы зарегистрировать функцию поиска, которая возвращает экземпляр CodecInfo настроен для кодека invertcaps.
импортных кодеков из codecs_invertcaps_charmap импортировать encoding_map, decoding_map # Кодер / декодер без сохранения состояния класс InvertCapsCodec (codecs.Codec): def encode (self, input, errors = 'strict'): return codecs.charmap_encode (ввод, ошибки, encoding_map) def decode (self, input, errors = 'strict'): return codecs.charmap_decode (ввод, ошибки, decoding_map) # Инкрементальные формы класс InvertCapsIncrementalEncoder (кодеки.IncrementalEncoder): def encode (self, input, final = False): вернуть codecs.charmap_encode (input, self.errors, encoding_map) [0] класс InvertCapsIncrementalDecoder (codecs.IncrementalDecoder): def decode (self, input, final = False): вернуть codecs.charmap_decode (input, self.errors, decoding_map) [0] # Читатель и писатель потока класс InvertCapsStreamReader (InvertCapsCodec, codecs.StreamReader): проходить класс InvertCapsStreamWriter (InvertCapsCodec, codecs.StreamWriter): проходить # Зарегистрируем функцию поиска кодеков def find_invertcaps (кодировка): "" "Вернуть кодек для invertcaps."" " если кодировка == 'invertcaps': кодеки возврата. name = 'invertcaps', encode = InvertCapsCodec (). кодировать, decode = InvertCapsCodec (). декодировать, incrementalencoder = InvertCapsIncrementalEncoder, incrementaldecoder = InvertCapsIncrementalDecoder, streamreader = InvertCapsStreamReader, streamwriter = InvertCapsStreamWriter, ) return None codecs.register (find_invertcaps) если __name__ == '__main__': # Кодер / декодер без сохранения состояния кодировщик = кодеки.getencoder ('инвертировать колпачки') текст = 'abc.DEF' кодированный_текст, потребленный = кодировщик (текст) print 'Кодировщик преобразовал "{}" в "{}", потребляя {} символов. формат ( текст, кодированный_текст, использованный) # Автор потока import sys Writer = codecs.getwriter ('invertcaps') (sys.stdout) напечатайте 'StreamWriter for stdout:', писатель.write ('abc.DEF') Распечатать # Инкрементальный декодер decoder_factory = codecs.getincrementaldecoder ('инвертировать колпачки') декодер = decoder_factory () decoded_text_parts = [] для c в кодированном_тексте: decoded_text_parts.добавить (decoder.decode (c, final = False)) decoded_text_parts.append (decoder.decode ('', final = Истина)) decoded_text = '' .join (decoded_text_parts) print 'IncrementalDecoder преобразовал "{}" в "{}"'. format ( кодированный_текст, декодированный_текст)
Базовым классом кодера / декодера без сохранения состояния является Codec. Переопределить encode () и decode () с вашей реализацией (в этом case, вызывая charmap_encode () и charmap_decode () соответственно). Каждый метод должен возвращать кортеж, содержащий преобразованные данные и количество входных байтов или символов потребляется.Удобно, что charmap_encode () и charmap_decode () уже возвращает эту информацию.
IncrementalEncoder и IncrementalDecoder служат базовые классы для дополнительных интерфейсов. Encode () и Decode () методы инкрементных классов определены в таких способ, которым они возвращают только фактические преобразованные данные. Любой информация о буферизации сохраняется как внутреннее состояние. В Кодировка invertcaps не требует буферизации данных (она использует однозначный отображение). Для кодировок, которые производят другой объем вывода в зависимости от обрабатываемых данных, например алгоритмов сжатия, BufferedIncrementalEncoder и BufferedIncrementalDecoder - более подходящие базовые классы, поскольку они управляют необработанной частью ввода за вас.
StreamReader и StreamWriter нуждаются в encode () и методы decode () тоже, и поскольку ожидается, что они вернут то же значение, что и версия из Codec, вы можете использовать несколько наследование для реализации.
$ python codecs_invertcaps_register.py Кодировщик преобразовал abc.DEF в ABC.def, используя 7 символов. StreamWriter для стандартного вывода: ABC.def IncrementalDecoder преобразовал "ABC.def" в "abc.DEF"
Обработка строк Unicode в Python
В Redis строковые значения могут содержать произвольные двоичные данные, например, вы может хранить изображение в формате jpeg.Когда вы сохраняете текст в виде строки в Redis и получаете это, вы получите объект байтов. Если вы хотите вернуть строку Unicode, используйте decode_responses = True при создании соединения / экземпляра Redis.
Также в Redis нет целочисленного, двойного или логического типа. Они хранятся как строковое значение. Когда вы сохраняете номер в ключе Redis, вы получаете строка в байтах или в юникоде. Как видно из примера:
#! / Usr / bin / env питон # coding = utf-8 "" "пример redis на python2 "" " импортировать Redis def test_redis (): conn = redis.StrictRedis (хост = 'localhost', порт = 6379, db = 0) conn.set (u'somestring ', u' ✓ правильно ') тип утверждения (conn.get (u'somestring ')) - str assert conn.get (u'somestring ') == b'✓ правильно' # нестроковых типов conn.set (u'someint ', 123) тип утверждения (conn.get (u'someint ')) - str assert conn.get (u'someint ') == b'123' conn.set (u'somedouble ', 123.1) тип утверждения (conn.get (u'somedouble ')) - str assert conn.get (u'somedouble ') == b'123.1' conn.set (u'somebool ', True) # не делайте этого.тип утверждения (conn.get (u'somebool ')) - str assert conn.get (u'somebool ') == b'True' conn.hset (u «somehash», «key1», '✓ правильно') conn.hset (u "somehash", "key2", '❌ неправильно') d = conn.hgetall (u "somehash") утверждать "key1" в d утверждать u'key1 'в d тип утверждения (d ['key1']) - байты assert d ['key1'] == u'✓ правильный '. encode (' utf-8 ') assert d ['key1']! = u '✓ правильно' def test_redis_auto_decode (): conn = redis.StrictRedis (host = 'localhost', порт = 6379, db = 0, decode_responses = True) соед.set (u'somestring ', u' ✓ правильно ') тип утверждения (conn.get (u'somestring ')) - юникод assert conn.get (u'somestring ') == u'✓ правильно' # нестроковых типов conn.set (u'someint ', 123) тип утверждения (conn.get (u'someint ')) - это юникод assert conn.get (u'someint ') == u'123' conn.set (u'somedouble ', 123.1) тип утверждения (conn.get (u'somedouble ')) - это юникод assert conn.get (u'somedouble ') == u'123.1' conn.hset (u «somehash», «key1», '✓ правильно') conn.hset (u "somehash", "key2", '❌ неправильно') d = соед.hgetall (у "somehash") утверждать "key1" в d утверждать u'key1 'в d тип утверждения (d ['key1']) - Unicode assert d ['key1'] == u'✓ правильно ' assert d ['key1']! = u '✓ правильно'. encode ('utf-8')
В python3 все становится немного неприятно. В python3 ключи и значения redis строго байты. Это особенно сложно при работе с хешами.
#! / Usr / bin / env python3 # coding = utf-8 "" "пример redis на python3 "" " импортировать Redis def test_redis (): conn = redis.StrictRedis (host = 'localhost', порт = 6379, db = 0) соед.set ('somestring', '✓ правильно') тип утверждения (conn.get ('somestring')) - байты assert conn.get ('somestring') == '✓ правильно'.encode (' utf-8 ') # нестроковых типов conn.set ('что-то', 123) тип утверждения (conn.get ('someint')) - байты assert conn.get ('someint') == b'123 ' conn.set ('некоторая двойка', 123.1) тип утверждения (conn.get ('somedouble')) - байты assert conn.get ('somedouble') == b'123.1 ' conn.set ('somebool', True) # не делайте этого. тип утверждения (conn.get ('somebool')) - байты утверждать конн.получить ('somebool') == b'True ' conn.hset (u «somehash», «key1», '✓ правильно') conn.hset (u "somehash", "key2", '❌ неправильно') d = conn.hgetall (u "somehash") утверждать "key1" не в d утверждать b'key1 'в d тип утверждения (d [b'key1 ']) - байты assert d [b'key1 '] ==' ✓ правильно '. encode (' utf-8 ') def test_redis_auto_decode (): conn = redis.StrictRedis (host = 'localhost', порт = 6379, db = 0, decode_responses = True) conn.set ('somestring', '✓ правильно') тип утверждения (соед.get ('somestring')) равно str assert conn.get ('somestring') == '✓ правильно' # нестроковых типов conn.set ('что-то', 123) тип утверждения (conn.get ('someint')) - str assert conn.get ('someint') == '123' conn.set ('некоторая двойка', 123.1) тип утверждения (conn.get ('somedouble')) - str assert conn.get ('somedouble') == '123.1' conn.hset ("somehash", "key1", '✓ правильно') conn.hset ("somehash", "key2", '❌ неправильно') d = conn.