python ascii codes to utf
In a (very small) nutshell, a Unicode code point is an abstract «thingy» representing one character 1 . Programmers like to work with these, because we like to think of strings as coming one character at a time. Unfortunately, it was decreed a long time ago that a character must fit in one byte of memory, so there can be at most 256 different characters. Which is fine for plain English, but doesn’t work for anything else. There’s a global list of code points — thousands of them — which are meant to hold every possible character, but clearly they don’t fit in a byte.
The solution: there is a difference between the ordered list of code points that make a string, and its encoding as a sequence of bytes. You have to be clear whenever you work with a string which of these forms it should be in.
To convert between the forms you can .encode() a list of code points (a Unicode string) as a list of bytes, and .decode() bytes into a list of code points. To do so, you need to know how to map code points into bytes and vice versa, which is the encoding. If you don’t specify one, Python 2.x will guess that you meant ASCII. If that guess is wrong, you will get a UnicodeError .
Note that Python 3.x is much better at handling Unicode strings, because the distinction between bytes and code points is much more clear cut.
EDIT: I guess I should point out how this helps. But you really should read the above links! Just throwing in .encode() s and .decode() s everywhere is a terrible way to code, and one day you’ll get bitten by a worse problem.
Anyway, if you step through what you’re doing in the shell you’ll see
>>> from HTMLParser import HTMLParser >>> text = "македонија" >>> hparser = HTMLParser() >>> text = hparser.unescape(text) >>> text u'\u043c\u0430\u043a\u0435\u0434\u043e\u043d\u0438\u0458\u0430'
I’m using Python 2.7 here, so that’s a Unicode string i.e. a sequence of Unicode code points. We can encode them into a regular string (i.e. a list of bytes) like
>>> text.encode("utf-8") '\xd0\xbc\xd0\xb0\xd0\xba\xd0\xb5\xd0\xb4\xd0\xbe\xd0\xbd\xd0\xb8\xd1\x98\xd0\xb0'
But we could also pick a different encoding!
>>> text.encode("utf-16") '\xff\xfe\x04=\x048\x04X\x040\x04'
You’ll need to decide what encoding you want to use.
What went wrong when you did it? Well, not every encoding understands every code point. In particular, the «ascii» encoding only understands the first 256! So if you try
>>> text.encode("ascii") Traceback (most recent call last): File "", line 1, in UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-9: ordinal not in range(128)
you just get an error, because you can’t encode those code points in ASCII.
When you do req.write , you are trying to write a list of code points down the request. But HTML requests don’t understand code points: they just use ASCII. Python 2 will try to be helpful by automatically ASCII-encoding your Unicode strings, which is fine if they really are ASCII but not if they aren’t.
So you need to do req.write(hparser.unescape(text).encode(«some-encoding»)) .
Кодирование строк
Чтобы компьютер смог отобразить передаваемые ему символы, они должны быть представлены в конкретной кодировке. Навряд ли найдется человек, который никогда не сталкивался с кракозябрами: открываешь интернет-страницу, а там – набор непонятных знаков; хочешь прочесть книгу в текстовом редакторе, а вместо слов получаешь сплошные знаки вопроса. Причина заключается в неверной процедуре декодирования текста (если сильно упростить, то программа пытается представить американцу, например, букву «Щ», осуществляя поиск в английском алфавите).
Возникают вопросы: что происходит, кто виноват? Ответ не будет коротким.
1. Компьютер – человек
Так сложилось, что компьютерная техника оперирует единицами и нулями. На вашей же клавиатуре представлено не менее 100 клавиш. Все, что вы вводите при печати, в итоге преобразуется в те самые бинарные величины.
В этом суть кодировки. ПК запоминает любые буквы, числа и знаки в виде определенного значения из единиц и нулей. Для примера: английская буква «Y» в двоичном коде выглядит как «0b1011001» , а в шестнадцатеричном как «0x59» .
Для осмысленного диалога пользователя и компьютера требуется двусторонний переводчик:
– «человеческие» строки необходимо перекодировать в байты;
– «компьютерную» речь требуется преобразовать в воспринимаемые пользователем осмысленные структуры.
В языке Python за это отвечают функции encode / decode . Важно кодировать и декодировать сообщение в одинаковой кодировке, чтобы не столкнуться с проблемой бессмысленных наборов символов.
2. ASCII
Так как первые вычислительные машины были малоемкими, для представления в их памяти всего набора требуемых знаков хватало 7 бит (или 128 символов). Сюда входил весь английский алфавит в верхнем и нижнем регистрах, цифры, знаки, вспомогательные символы.
Поначалу этого вполне хватало. Кодировка получила имя ASCII (читается как «аски» или «эски»). В Пайтоне вы и сегодня можете посмотреть на символы ASCII. Для этого имеется встроенный модуль string .
import string print(string.ascii_letters) print(string.digits) print(string.punctuation) Результат выполнения кода abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 !"#$%&'()*+,-./:;?@[\]^_`<|>~
С другими свойствами модуля можете ознакомиться самостоятельно.
Время шло, компьютеризация общества ширилась, 128 символов стало не хватать. Оставшийся последний 8-ой бит также выделили для кодирования (а это еще 128 знаков). В итоге появилось большое количество кодировок (кириллическая, немецкая и т.п.). Такая ситуация привела к проблемам. Уже в то время англичанин, получающий электронное письмо из России, мог увидеть не русские буквы, а набор непонятных закорючек.
Потребовалось указание кодировок в заголовках документов.
3. Юникод-стандарт
Как вы считаете, сколько нужно символов, чтобы хватило всем и навсегда? 10_000? Конечно, нет. Уже сегодня более 100_000 знаков имеет свое числовое представление. И это не предел. Люди постоянно придумывают новые «буквы».
Откройте свой телефон и создайте пустое сообщение. Зайдите в раздел «смайликов». Да их тут больше сотни! И это не картинки в большинстве своем. Они являются символами определенной кодировки. Если вы застали времена, когда SMS-технологии только начинали развиваться, то этих самых «смайлов» было не более десятка. Лет через 10 их количество станет «неприличным».
Упомянутая выше кодировка ASCII в своем расширенном варианте породила большое количество новых. Основная беда: имея 128 вариантов обозначить символ, мы никак не сумеем внедрить туда буквы других языков. В частности, какой-нибудь символ под номером 201 в кириллице даст совсем не русскую букву, если отослать его в Румынию. Следовательно, говоря кому-то «посмотри на 201-ый символ» мы не даем никакой гарантии, что собеседник увидит то же.
Для решения задачи был разработан стандарт Unicode. Отметим, что это не определенная кодировка, а именно набор правил. Суть юникода – связь символа и определенного числа без возможного повторения. Если мы кого-то попросим показать символ, скрытый под номером «1000», то в любой точке планеты он будет одним и тем же графическим элементом.
how to change the ascii character into utf-8 with python?
A9 stand for © in ascii table ,how can i change A9 in ascii encoding into utf-8 encoding in python?What is the rule for asii encoding be changed into utf-8?
Can you explain what you are actually trying to accomplish, maybe that will help us because the question does not make sense.
«©» is an extended ASCII character,its value is a9 ,you can get it in aboutmyip.com/AboutMyXApp/AsciiChart.jsp.
@it_is_a_literature: and there is no standard for extended ASCII; it is a term that carries no reliable meaning. Last but not least, you didn’t use the term extended ASCII, you talked about just plain ASCII. In computer programming, precision is important.
1 Answer 1
Any given ASCII codepoint is equal to the UTF-8 encoding for that codepoint. This is deliberate.
However, © is not an ASCII codepoint, it is a Latin-1 codepoint. ASCII is a 7-bit standard and codepoints run from 00 through to 7F. Beyond that, Latin 1 (ISO-8859-1) runs from U+0080 to U+00FF, requiring 2 UTF-8 bytes per codepoint to encode.
Just decode from Latin 1, encode to UTF-8:
>>> b'\xA9'.decode('latin1').encode('utf8') b'\xc2\xa9'
As for the ‘rules’ of UTF-8, it’s best explained in the UTF-8 Wikipedia article.
For Latin-1 codepoints, whose values fit in a single byte, the rule is simple: the top 2 bits (either 10 or 11 ) form the lower two bits of the first byte, together with 110000 as the high bits. The lower 6 bits of the codepoint are given 10 as the high bits.
A9 , or 10101001 then becomes 11000010 10101001 or C2 A9 :
10 101001 Latin-1 codepoint A9 .. ------ / \ 11000010 10101001 UTF-8 encoding C2 A9 .. ------