Как я могу понять плохо кодированное сообщение?

--------------------------- ƒGƒ‰[ --------------------------- ƒfƒBƒXƒvƒŒƒCƒ‚[ƒh‚ªÝ'è‚Å‚«‚Ü‚¹‚ñ. --------------------------- OK --------------------------- 

Я получаю это ясное сообщение об ошибке из системы 4 Уединения Shooter , после того, как я передам ему эту версию d3drm.dll (вздох).

Вот вам hexdump для вашего удобства:

 00000000 c6 92 66 c6 92 42 c6 92 58 c6 92 76 c6 92 c5 92 |..f..B..X..v....| 00000010 c6 92 43 c6 92 e2 80 9a c2 81 5b c6 92 68 e2 80 |..C.......[..h..| 00000020 9a c2 aa c2 90 c3 9d e2 80 99 c3 a8 e2 80 9a c3 |................| 00000030 85 e2 80 9a c2 ab e2 80 9a c3 9c e2 80 9a c2 b9 |................| 00000040 e2 80 9a c3 b1 2e 0a |.......| 00000047 

Как бы вы превратили это в последовательное сообщение об ошибке – то есть, как вы собираетесь найти правильную пару для кодирования / декодирования для этого сообщения об ошибке?


Вот что я пробовал.

Я думаю, проблема заключается в том, что разработчик использовал неправильные настройки кодировки для этого сообщения (учитывая возраст игры, разработанный для WinXP, это неудивительно). Посмотрев на это, можно предположить, что сообщение было закодировано в виде многобайтовой кодировки ( ƒf ƒB ƒX ƒv ƒŒ .)

Однако каждая группа, по-видимому, состоит из трех байтов (переменная?). Это исключает обычных подозреваемых:

 >>> wat = "ƒfƒBƒXƒvƒŒƒCƒ‚[ƒh‚ªÝ'è‚Å‚«‚Ü‚¹‚ñ. " >>> wat.encode("UTF-8").decode("UTF-32") UnicodeDecodeError: 'utf32' codec cannot decode bytes in position 0-3: codepoint not in range(0x110000) >>> wat.encode("UTF-8").decode("UTF-16") UnicodeDecodeError: 'utf16' codec cannot decode bytes in position 70-70: truncated data >>> wat.encode("UTF-8")[:-1].decode("UTF-16") '鋆왦䊒鋆왘皒鋆鋅鋆왃\ue292骀臂왛梒胢슚슪쎐\ue29d馀ꣃ胢쎚\ue285骀ꯂ胢쎚\ue29c骀맂胢쎚⺱' #meaningless according to Google Translate. 鋆왃 >>> wat = "ƒfƒBƒXƒvƒŒƒCƒ‚[ƒh‚ªÝ'è‚Å‚«‚Ü‚¹‚ñ. " >>> wat.encode("UTF-8").decode("UTF-32") UnicodeDecodeError: 'utf32' codec cannot decode bytes in position 0-3: codepoint not in range(0x110000) >>> wat.encode("UTF-8").decode("UTF-16") UnicodeDecodeError: 'utf16' codec cannot decode bytes in position 70-70: truncated data >>> wat.encode("UTF-8")[:-1].decode("UTF-16") '鋆왦䊒鋆왘皒鋆鋅鋆왃\ue292骀臂왛梒胢슚슪쎐\ue29d馀ꣃ胢쎚\ue285骀ꯂ胢쎚\ue29c骀맂胢쎚⺱' #meaningless according to Google Translate. 

Я выбрал UTF-8 как начальную кодировку, потому что ASCII не работал ( UnicodeEncodeError: 'ascii' codec can't encode character '\u0192' in position 0: ordinal not in range(128) ), а UTF-8 должен быть стандартная кодировка для Windows 7 в любом случае (OS, которую я пытался использовать.)


Не совсем.

Каби может быть на что-то, но это не полная история. Во-первых, я не могу воспроизвести его кодировку:

 >>> print (wat.encode("UTF-8").decode("Shift-JIS")) UnicodeDecodeError: 'shift_jis' codec cannot decode bytes in position 22-23: illegal multibyte sequence >>> print (wat.encode("UTF-8")[:22].decode("Shift-JIS"))ニ断ニ達ニ湛ニ致ニ椎槌辰ニ停 

Википедия говорит, что там очень похожая кодировка: cp932.

 >>> print(wat.encode("UTF-8").decode("932")) UnicodeDecodeError: 'cp932' codec cannot decode bytes in position 44-45: illegal multibyte sequence >>> print(wat.encode("UTF-8")[:44].decode("932"))ニ断ニ達ニ湛ニ致ニ椎槌辰ニ停喙ニ檀窶堋ェテ昶凖ィ窶堙 

Опять же, очень отличается от того, что он вставлял. Давайте посмотрим, однако:

 >>> print("ディスプレイモ\x81[ドが\x90ン定できません.\n")ディスプレイモ[ドがン定できません. 

Однако это мусор для Google Translate. Затем я попытался удалить некоторые кусочки. Учитывая, что デ ィ ス プ レ イ означает «отображение», если я удаляю «мусор» вокруг битов, которые невозможно декодировать, я получаю:

  ディスプレイモ\x81[ドが\x90ン定できません. → ディスプレイ ドが ン定できません. → The display mode is not specified. 

Однако, так как я спросил об этом, это не полная история. Что с этими байтами, которые невозможно декодировать? Как вы можете получить эти байты для начала.

3 Solutions collect form web for “Как я могу понять плохо кодированное сообщение?”

=== файл disupure.py ===

 # start with the OP's hex dump: hexbytes = """ c6 92 66 c6 92 42 c6 92 58 c6 92 76 c6 92 c5 92 c6 92 43 c6 92 e2 80 9a c2 81 5b c6 92 68 e2 80 9a c2 aa c2 90 c3 9d e2 80 99 c3 a8 e2 80 9a c3 85 e2 80 9a c2 ab e2 80 9a c3 9c e2 80 9a c2 b9 e2 80 9a c3 b1 2e 0a """ strg = ''.join( chr(int(hexbyte, 16)) for hexbyte in hexbytes.split() ) uc = strg.decode('utf8') # decodes OK but result is gibberish uc_hex = ' '.join("%04X" % ord(x) for x in uc) print uc_hex # but it's stuffed ... U+0192??? oh yeah, 0x83 badenc = 'cp1252' # sort of, things like 0x81 have to be allowed for fix_bad = {} for i in xrange(256): b = chr(i) try: fix_bad[ord(b.decode(badenc))] = i except UnicodeDecodeError: fix_bad[i] = i recoded = uc.translate(fix_bad).encode('latin1') better_uc = recoded.decode('cp932') # It's on Windows; cp932 what would have been used # but 'sjis' gives the same answer better_uc_hex = ' '.join("%04X" % ord(x) for x in better_uc) print better_uc_hex print repr(better_uc) print better_uc 

Результат выполнения этого в IDLE (пустые строки добавлены для ясности):

 0192 0066 0192 0042 0192 0058 0192 0076 0192 0152 0192 0043 0192 201A 0081 005B 0192 0068 201A 00AA 0090 00DD 2019 00E8 201A 00C5 201A 00AB 201A 00DC 201A 00B9 201A 00F1 002E 000A 30C7 30A3 30B9 30D7 30EC 30A4 30E2 30FC 30C9 304C 8A2D 5B9A 3067 304D 307E 305B 3093 002E 000A u'\u30c7\u30a3\u30b9\u30d7\u30ec\u30a4\u30e2\u30fc\u30c9\u304c\u8a2d\u5b9a\u3067\u304d\u307e\u305b\u3093.\n'ディスプレイモードが設定できません. 

Переводчик Google: вы можете установить режим отображения.

Microsoft (Bing) Translate: Режим отображения не установлен.

Обновление. Еще немного объяснений о том, зачем нужна таблица перевода и почему она сопоставляет \x81 т. Д. С U + 0081, из статьи Википедии на cp1252 :

Согласно информации о веб-сайтах Microsoft и Unicode Consortium, позиции 81, 8D, 8F, 90 и 9D не используются. Однако вызов Windows API для преобразования с кодовых страниц в Unicode сопоставляет их с соответствующими управляющими кодами C1.

Очевидно.

Поскольку это японская игра

'デ ィ ス プ レ イ モ \ x81 [ド が \ x90 ン 定 で き ま せ ん. \ П'

«Disupureimo \ x81 [приложения de \ x90 не могут быть исправлены. \ N '

Поскольку я вставил строку, некоторые из них отсутствуют.

Кодирование называется Shift-JIS. Я использую свою Opera, чтобы показать персонажей на самом деле.

EDIT: К сожалению, все мои браузеры не могут добавлять комментарии к SO. Я думаю, что речь идет о сети. Поэтому я должен обновить здесь.

Вероятно, вы должны настроить режим отображения на 256 цветов. Это много японской игры.

EDIT2: Интересная история.

О том, как я получил строку, которая является самой забавной вещью, заключается в том, что я НЕ НЕОБХОДИМО прямо кодировать исходные байты в нее, поскольку вы можете попробовать, только получили это:

ニ 断 ニ 達 ニ 湛 ニ 致 ニ 椎 槌 辰 ニ 停 堋 ー ニ 檀 窶 堋 ェ ツ 静 昶 凖 ィ 窶 堙 堋 ォ 窶 堙 懌 堋 ケ 窶 堙 ア.

Но вставка строки в другую веб-страницу в качестве источника, а затем использование Opera изменило кодировку на Shift-JIS.

У Opera есть эта функция, которая позволяет изменять исходный код веб-страницы и показывать ее. Поэтому я написал такую ​​страницу, как:

 <!DOCTYPE html> <head> <title>test</title> </head> <body> 'ƒfƒBƒXƒvƒŒƒCƒ‚ƒh‚ªÝ'è‚Å‚«‚Ü‚¹‚ñ. </body> </html> 

и вот что я получил:

«デ ィ ス プ レ イ モ ド が ン 定 で き ま せ ん.

Что еще более бессмысленно. И вы попробовали изменить цветной режим до 256 цветов?

Может быть, это поможет:

 from binascii import unhexlify data = '''\ c6 92 66 c6 92 42 c6 92 58 c6 92 76 c6 92 c5 92 c6 92 43 c6 92 e2 80 9a c2 81 5b c6 92 68 e2 80 9a c2 aa c2 90 c3 9d e2 80 99 c3 a8 e2 80 9a c3 85 e2 80 9a c2 ab e2 80 9a c3 9c e2 80 9a c2 b9 e2 80 9a c3 b1 2e 0a ''' data = unhexlify(data.replace(' ','').replace('\n','')) print data.decode('utf8').encode('windows-1252','xmlcharrefreplace').decode('shift-jis') 

Вывод

 ディスプレイモ&#129;[ドが&#144;ン定できません. 

Шестнадцать данных, которые вы предоставили, были Shift_JIS, декодированные как windows-1252, а затем перекодированные как UTF-8.

редактировать

Основываясь на ответе Джона Мачина:

 from binascii import unhexlify import re data = '''\ c6 92 66 c6 92 42 c6 92 58 c6 92 76 c6 92 c5 92 c6 92 43 c6 92 e2 80 9a c2 81 5b c6 92 68 e2 80 9a c2 aa c2 90 c3 9d e2 80 99 c3 a8 e2 80 9a c3 85 e2 80 9a c2 ab e2 80 9a c3 9c e2 80 9a c2 b9 e2 80 9a c3 b1 2e 0a ''' data = unhexlify(data.replace(' ','').replace('\n','')) data = data.decode('utf8').encode('windows-1252','xmlcharrefreplace') # convert the XML entities that windows-1252 couldn't encode back into bytes data = re.sub(r'&#(\d+);',lambda x: chr(int(x.group(1))),data) print data.decode('shift-jis') 

Вывод

 ディスプレイモードが設定できません. 
Python - лучший язык программирования в мире.