получить код символа utf-8 с учетом кода символа shift-jis?

В моей программе я получаю коды символов shift-jis как целые числа Python, которые мне нужно преобразовать в соответствующие коды символов utf8 (которые также должны быть в целых числах). Как я могу это сделать? Для ASCII у вас есть полезные функции ord () / chr (), которые позволяют конвертировать целое число в строку ASCII, которую вы можете легко преобразовать в Unicode позже. Ничего подобного для других кодировок найти не могу.

Используя Python 2.

РЕДАКТИРОВАТЬ: окончательный код. Спасибо всем:

def shift_jis2unicode(charcode): # charcode is an integer
    if charcode <= 0xFF:
        string = chr(charcode)
    else:
        string = chr(charcode >> 8) + chr(charcode & 0xFF)

    return ord(string.decode('shift-jis'))

print shift_jis2unicode(8140)

person Alex C    schedule 24.02.2012    source источник
comment
Необычно получать их как целые числа, а не как байты - это что-то, что вы можете изменить?   -  person Thomas K    schedule 24.02.2012
comment
Извини не могу. Кстати, я думаю, что байты - это что-то новое в Python 3, я использую 2.   -  person Alex C    schedule 24.02.2012
comment
Python 2 str работает как байты и имеет псевдоним bytes в 2.6 и 2.7.   -  person Thomas K    schedule 24.02.2012
comment
Что ж, если бы я мог. Вот почему я разместил этот вопрос. Если бы я мог получить его как строку, я мог бы просто выполнить mystr.decode ('shift_jis'), а затем ord () для этого. Но я не могу.   -  person Alex C    schedule 24.02.2012
comment
Покажите несколько примеров данных, чтобы лучше понять, с чем вы работаете.   -  person Ignacio Vazquez-Abrams    schedule 24.02.2012
comment
ord() даст вам кодовые точки Unicode, а не utf-8. Это может быть то, что вы хотите, но это совсем разные вещи.   -  person Thomas K    schedule 24.02.2012
comment
Извините, но, кажется, я объяснил, что у меня есть и что мне нужно с этим делать.   -  person Alex C    schedule 24.02.2012
comment
Томас К: Думаю, ты прав. Тем не менее, я даже не дошел до этого: я даже не знаю, как преобразовать код целочисленного символа в строку кодировки shift-jis.   -  person Alex C    schedule 24.02.2012
comment
Пожалуйста, не используйте string в качестве имени переменной.   -  person Mark Ransom    schedule 25.02.2012
comment
Я думал, что это str, которая была зарезервирована. Во всяком случае, даже не в функции?   -  person Alex C    schedule 25.02.2012
comment
str - это встроенный тип. строка - это встроенный модуль. Технически вы можете использовать их для имен переменных, но это сбивает с толку. Лучше избегать их.   -  person user9876    schedule 25.02.2012


Ответы (3)


Не существует такой вещи, как «коды символов utf8 (которые также должны быть целыми числами)».

Unicode определяет «кодовые точки», которые являются целыми числами. UTF-8 определяет, как преобразовать эти кодовые точки в массив байтов.

Итак, я думаю, что вам нужны кодовые точки Unicode. В этом случае:

def shift_jis2unicode(charcode): # charcode is an integer
    if charcode <= 0xFF:
        shift_jis_string = chr(charcode)
    else:
        shift_jis_string = chr(charcode >> 8) + chr(charcode & 0xFF)

    unicode_string = shift_jis_string.decode('shift-jis')

    assert len(unicode_string) == 1
    return ord(unicode_string)

print "U+%04X" % shift_jis2unicode(0x8144)
print "U+%04X" % shift_jis2unicode(0x51)

(Также: я не думаю, что 8100 - допустимый код символа shift-JIS ...)

person user9876    schedule 24.02.2012
comment
8100 был своего рода предположением и ошибкой. Не поймите весь бизнес Unicode и utf-8. Я думаю, что вы правы. - person Alex C; 25.02.2012
comment
@AlexC, строки Unicode состоят из кодовых точек (обычно по одной на символ), а ord преобразует кодовую точку в целое число. UTF-8 - это представление кодовой точки в 1 или более 8-битных байтах. - person Mark Ransom; 25.02.2012
comment
Для хорошего введения в Unicode и все проблемы с кодировкой я рекомендую "Абсолютный минимум". Каждый разработчик программного обеспечения должен абсолютно точно знать о Unicode и наборах символов (без оправданий!) - joelonsoftware.com/articles/Unicode.html - person user9876; 02.03.2012

Возможно, есть лучший способ сделать это, но, поскольку других ответов пока нет, вот вариант.

Для преобразования целых чисел shift-jis в кодовые точки Unicode, затем используйте unichr() для преобразования ваших данных в объект Unicode Python, а затем преобразовать его из Unicode в utf8 с помощью unicode.encode('utf-8').

person Andrew Clark    schedule 24.02.2012
comment
Спасибо. Я уже использую нестандартную таблицу. Я подумал, что если бы я мог использовать то, что предоставляет Python, код был бы чище, и мне не нужно было бы иметь дополнительный файл, содержащий все коды символов. - person Alex C; 24.02.2012

person    schedule
comment
Что делает chr (c ›› 8) + chr (c & 0xff)? - person Alex C; 24.02.2012
comment
@AlexC, c>>8 сдвигает верхние 8 бит целого числа в нижние 8 бит, а c&0xff удаляет верхние 8 бит. Это способ разбить целое число на две 8-битные части. chr преобразуется в символ, как вы знаете, а + добавляет их в двухсимвольную строку. - person Mark Ransom; 25.02.2012
comment
OK. Теперь у меня проблемы с преобразованием строки Unicode в целое число кода символа utf-8. Я обновлю свой вопрос кодом, который у меня есть, пожалуйста, посмотрите. - person Alex C; 25.02.2012
comment
@AlexC, я думаю, вам нужно 0x8100, а не 8100 в вашем тестовом коде. - person Mark Ransom; 25.02.2012
comment
Я думаю, что 0xFF и 255 - это одно и то же в Python. Все равно ошибка. - person Alex C; 25.02.2012
comment
@AlexC, да, 0xFF и 255 - это одно и то же, но я не об этом. 0x8100 - допустимый символ shift-j, а 8100 - нет. - person Mark Ransom; 25.02.2012
comment
Это? Кодек shift-jis не может его декодировать. В любом случае настоящая проблема заключается в том, что ord () принимает символ (строку длиной 1), в то время как мы передаем ему двухбайтовую строку. Надо подумать о другом ... - person Alex C; 25.02.2012
comment
@AlexC, вы пробовали запустить именно тот код, который я вам дал? Он должен работать нормально, возвращая список целых чисел, каждый из которых является байтом utf-8. - person Mark Ransom; 25.02.2012
comment
@AlexC, извините, что вы правы - 0x8100 недействителен shift-jis, он начинается с 0x8140. - person Mark Ransom; 25.02.2012