Найти - Пользователи
Полная версия: Определение символов UTF8 из бинарного кода(нужна помощь)
Начало » Python для экспертов » Определение символов UTF8 из бинарного кода(нужна помощь)
1
sonniy
есть вот такая таблица(оригинал) :

Unicode UTF-8 Представленные символы
0x00000000 — 0x0000007F 0xxxxxxx ASCII, в том числе латинский алфавит, простейшие знаки препинания и арабские цифры
0x00000080 — 0x000007FF 110xxxxx 10xxxxxx кириллица, расширенная латиница, арабский, армянский, греческий, еврейский и коптский алфавит; сирийское письмо, тана, нко; МФА; некоторые знаки препинания
0x00000800 — 0x0000FFFF 1110xxxx 10xxxxxx 10xxxxxx все другие современные формы письменности, в том числе грузинский алфавит, индийское, китайское, корейское и японское письмо; сложные знаки препинания; математические и другие специальные символы
0x00010000 — 0x001FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx музыкальные символы, редкие китайские иероглифы, вымершие формы письменности

с хексовыми значениями понятно:
0 — 127 занимает один байт
128 — 2047 два байта
2048 — 65535 три байта
65535 — 2097151 четыре байта
это номера символов, достать их можно так:
>>> unichr(2047)
u'\u07ff'
посмотреть его вид так :
>>> print unichr(2047)
߿
убедится сколько он занимает байт так :
>>> len(unichr(2047).encode('utf8'))
2
стоит задача принимать информацию которая выглядит примерно так :
11000000 10000000 11010100 10001000 11000110 10000001 11000111 10110000 11001001 10111111

я знаю что это бинарные значения символов utf8, но не знаю как их конвертировать к нормальному виду

может кто нибудь сталкивался с подобной ситуацией?
sonniy
нашел как конвертировать в hex и обратно :
вариант 1:
>>> import binascii
>>> binascii.b2a_hex('h')
'68'
>>> binascii.a2b_hex('68')
'h'
>>> chr(int('68',16))
'h'
вариант 2:
>>> 'h'.encode('hex_codec')
'68'
>>> '68'.decode('hex_codec')
'h'
ограничено символами ASCII
py.user.next
в третьем питоне
>>> s = '11010100 10001000 11000110 10000001 11000111 10110000 11001001 10111111'
>>> b = bytes(int(octet, 2) for octet in s.split())
>>> b
b'\xd4\x88\xc6\x81\xc7\xb0\xc9\xbf'
>>> b.decode()
'ԈƁǰɿ'
>>>
sonniy
я так понимаю , что можно иногда нарваться на несуществующий символ :
>>> s='1110001 10001101 10110111'
>>> b = bytes(int(octet, 2) for octet in s.split())
>>> b.decode()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf8' codec can't decode byte 0x8d in position 1: invalid start byte
>>> b
b'q\x8d\xb7'
>>> s='11100000 10001101 10110111 00000001'
>>> b = bytes(int(octet, 2) for octet in s.split())
>>> b
b'\xe0\x8d\xb7\x01'
>>> b.decode()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf8' codec can't decode bytes in position 0-1: invalid continuation byte
это следствие того, что номеров символов меньше чем комбинаций с байтами
я сначала грешил на проблему декода с трехбайтового, но :
>>> s='11100010 10001101 10110111'
>>> b = bytes(int(octet, 2) for octet in s.split())
>>> b.decode()
'&#9079;'
все как видите нормально, жаль что 2.х питон не поддерживает такие вещи
o7412369815963
sonniy
жаль что 2.х питон не поддерживает такие вещи
какие?
>>> s='11100010 10001101 10110111'
>>> b = ''.join([chr(int(octet, 2)) for octet in s.split()])
>>> print b.decode('utf8')
&#9079;
sonniy
Спасибо за помощь !

возник еще один вопрос :
может есть какой то способ переслать сообщение именно в байтовом виде ?
интересует передача такого рода через сокетное соединение
import socket
HOST = "127.0.0.1"
PORT = 7755

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))
data = u'могучая стринга'
byte = bytes([int('11100010',2)])

sock.send(byte+data)
суть в том чтобы всунуть перед сообщениями не символ а именно байт и именно такой как мне хочется …
nerijus
Для преобразования смотри модуль struct.
o7412369815963
> суть в том чтобы всунуть перед сообщениями не символ а именно байт и именно такой как мне хочется …

обычная “строка” является набором байтов, конвертировать “число в байт” и обратно можно через: chr, ord. строку u'abc' через encode, decode.
см это
sonniy
Спасибо, очень помогло
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB