Як я можу визначити дивного персонажа?


10

Я намагаюся визначити дивного персонажа, який я знайшов у файлі, з яким працюю:

$ cat file
�
$ od file
0000000 005353
0000002
$ od -c file
0000000 353  \n
0000002
$ od -x file
0000000 0aeb
0000002

Файл використовує кодування ISO-8859 і не може бути перетворений в UTF-8:

$ iconv -f ISO-8859 -t UTF-8 file
iconv: conversion from `ISO-8859' is not supported
Try `iconv --help' or `iconv --usage' for more information.
$ iconv  -t UTF-8 file
iconv: illegal input sequence at position 0
$ file file
file: ISO-8859 text

Моє головне питання - як я можу інтерпретувати вихідні дані odтут? Я намагаюся використовувати цю сторінку, яка дозволяє мені перекладати між різними представленнями символів, але це говорить мені, що 005353"шістнадцятковий код" - це те, що не здається правильним, а 0aeb"шістнадцятковий код" - це, знову ж таки, здається неправильним .

Отже, як я можу використовувати будь-якого з трьох варіантів ( 355, 005353або 0aeb) , щоб з'ясувати , який характер вони повинні представляти?

І так, я намагався з інструментами Unicode, але він, схоже, не є дійсним символом UTF:

$ uniprops $(cat file)
U+FFFD ‹�› \N{REPLACEMENT CHARACTER}
    \pS \p{So}
    All Any Assigned Common Zyyy So S Gr_Base Grapheme_Base Graph X_POSIX_Graph
       GrBase Other_Symbol Print X_POSIX_Print Symbol Specials Unicode

якщо я розумію опис символу Unicode U + FFFD, це зовсім не справжній символ, а заповнювач пошкодженого символу. Що має сенс, оскільки файл насправді не кодується UTF-8.


5
EB може бути δ в кодовій сторінці 437 , або Ù в кодовій сторінці 850 , або ë в 8859-1 ; хтось із них має сенс? ( iconvскаржиться, що ви не вказали вихідний набір символів, тому він використовує за замовчуванням, що, ймовірно, UTF-8.)
Стівен Кітт,

@StephenKitt так, ëце те, що я бачу, коли дані використовуються в іншій програмі! Але як я можу це знати? Чи не десь у даних, які я надаю? Як ви його знайшли? Про , я спробував iconvз , -f ISO-8859але вона скаржилася conversion from ISO-8859 "не supported`.
terdon

1
Арг! Я бачу, мені потрібно було просто використовувати ebі ігнорувати 0xшестнадцятковий індикатор або все, що це є. Моє незнання подібного роду глибоке. Чи можете ви опублікувати відповідь, пояснюючи це @StephenKitt?
тердон

5
Ваша ключова помилка тут полягає в тому, що ISO-8859 - це не ім'я кодування. Це сімейство кодувань; Мабуть, той, кого ви шукаєте, це ISO-8859-1.
трійчатка

1
Тоді ваш iconvби досяг успіху; та / або ви могли це шукати, наприклад, у Вікіпедії. Для цього дуже специфічного кодування також працює fileformat.info/info/unicode/char/00eb/index.htm (Unicode еквівалентний ISO-8859-1 в діапазоні 128-255, хоча, звичайно, жодне кодування UTF не сумісне з ним ).
трійчатка

Відповіді:


22

Ваш файл містить два байти, EB та 0A у шістнадцятковій формі. Ймовірно, що у файлі використовується набір символів з одним байтом на символ, наприклад ISO-8859-1 ; у цьому наборі символів EB - це:

$ printf "\353\n" | iconv -f ISO-8859-1
ë

Інші кандидати будуть δ в кодовій сторінці 437 , Ù в кодовій сторінці 850 ...

od -xВихідні дані в цьому випадку заплутані через витривалість; кращим варіантом є -t x1використання байтів:

$ printf "\353\n" | od -t x1
0000000 eb 0a
0000002

od -xкарти, до od -t x2яких зчитується два байти одночасно, а в системах малої ендіанії видає байти у зворотному порядку.

Якщо ви натрапили на такий файл, який не є дійсним UTF-8 (або не має сенсу, коли його інтерпретують як файл UTF-8), не існує надійного способу автоматичного визначення його кодування (та набору символів). Контекст може допомогти: якщо це файл, створений на західному ПК за останні пару десятиліть, є велика ймовірність, що він закодований в ISO-8859-1, -15 (варіант Євро) або Windows-1252; якщо він старший за це, CP-437 та CP-850 є ймовірними кандидатами. Файли зі східноєвропейських систем, або російських систем, або азіатських систем використовували б різні набори символів, про які я мало знаю. Тоді є EBCDIC ... iconv -lперелічить усі набори символів, iconvпро які відомо, і ви можете продовжувати випробування та помилки звідти.

(Я одного разу я напам'ять знав більшість CP-437 та ATASCII. Це були дні.)


1
Гаразд, на сторінці вікіпедії, на яку ви посилаєтесь, я бачу, що ëописано як 00EBі 234. Які додаткові 00? І чому це не так, 355як я очікував від odрезультатів? Я намагаюся отримати більш загальну відповідь про те, як я можу використовувати odвихід для ідентифікації персонажа. Чи можете ви пояснити щось про інтерпретацію шістнадцяткових кодів та / або яку інформацію потрібно для того, щоб визначити невідомий символ (кодування та інше)?
terdon

ЕВ становить 353 в восьмикутнику (не 355). Спробую узагальнити ...
Стівен Кітт

Ну, вибачте, я мав на увазі 353. Таким чином, 353 - вісімкове уявлення, а не десяткове. Арг.
terdon

1
Так, "o" у odзначенні восьмеричного ;-).
Стівен Кітт

1
У будь-якому випадку (U + FFFD) термінальний емулятор відображатиметься як заміна того байта 0xeb, який не утворює дійсного символу в UTF-8. Не ясно, чому uniprops $(cat file)(відсутні цитати btw) повідомили б про це (я не знаю про цю unipropsкоманду). unicode "$(cat file)"на Debian виводиться так, Sequence '\xeb' is not valid in charset 'UTF-8'як я очікував.
Стефан Шазелас

5

Зауважте, що odце короткий термін для восьмеричного дампа , так 005353це два байти як вісімкове слово, він od -xє 0aebшістнадцятковим як слово, а власне вміст вашого файлу - два байти, ebа 0aв шістнадцятковій - у цьому порядку.

Тож і те, 005353і інше 0aebне можна інтерпретувати як "шістнадцятковий код".

0a- це канал рядків (LF) і ebзалежить від кодування. fileпросто здогадується про кодування, це може бути що завгодно. Без будь-якої додаткової інформації, звідки прийшов файл тощо, це буде важко знайти.


Я розумію, що це тому, що я не розумію, як працюють кодові точки (або насправді шістнадцяткові), але як я можу це знати? Я зазвичай використовую, od -cоскільки це дає результат, який я можу зрозуміти. Як я міг використати те, 355що створює, щоб ідентифікувати персонажа? І чому це друк 0aebзамість того, eb0aякщо 0aце новий рядок?
terdon

@terdon endianness ... Дивіться мою оновлену відповідь.
Стівен Кітт

2

Неможливо зі 100% точністю здогадатися про набір текстових файлів.

Такі інструменти, як chardet , firefox , file -i, коли не визначено явної інформації про шаблони (наприклад, якщо HTML містить мета-діаграму = ... в голові, все простіше), спробують використовувати евристику, яка не така вже й погана, якщо текст досить великий.

Далі я демонструю виявлення діаграми за допомогою chardet( pip install chardet/ apt-get install python-chardetпри необхідності).

$ echo "in Noël" | iconv -f utf8 -t latin1  | chardet
<stdin>: windows-1252 with confidence 0.73

Після того , як кандидат добре кодувань, ми можемо використовувати iconv, recodeабо аналогічні зміни файл кодового до вашої «активної» кодуванні (в моєму випадку UTF-8) і подивитися , якщо він вгадав правильно ...

iconv -f windows-1252  -t utf-8 file

Деякі шаблони (як iso-8859-3, iso-8859-1) мають багато спільних символів - іноді непросто зрозуміти, чи знайшли ми ідеальний шарсет ...

Тому дуже важливо мати метадані, пов'язані з відповідним текстом (наприклад, XML).


Хм. Я не можу це відтворити, він просто руйнується. Але в будь-якому випадку, чи не просто це сказало мені кодування файлу? Моя проблема полягає у визначенні символу, а не кодування файлу. Це я вже знав.
terdon

1
Вибачте, я не зрозумів питання (моя звичайна проблема - це визначення шаблону). якщо тепер кодування, iconv -f ... -t utf-8 покаже вам символи?
JJoao

Ні. Я показую кодування саме там. Був один конкретний символ, який не підтримується цим кодуванням, і саме цей символ я намагався ідентифікувати.
terdon

1
Iso-8859 - це не кодування! кодування є iso-8850-1. iso-8859 - ізостандарт, який включає декілька визначень шасі. Спробуйтеfile -i ...
JJoao

1
@terdon, вибачте, що наполягаєте, але, усі хитрощі, якими ви спробували, працювали з правильним шаблоном. Напр .: iconv -f ISO-8859-1 -t UTF-8 file
JJoao

0
#!/bin/bash
#
# Search in a file, a known (part of a ) String (i.E.: Begrüßung),
# by testing all encodings
#
[[ $# -ne 2 ]] && echo "Usage: encoding-finder.sh FILE fUnKy_CHAR_FOR_SURE_IN_FILE" && exit
FILE=$1
PATTERN=$2
for enc in $( iconv -l | sed 's/..$//') 
do 
    iconv -f $enc -t UTF-8 $FILE  2>/dev/null | grep -m 1 $PATTERN && echo $enc 
done 

Якщо я отримаю файл, який містить, наприклад, для Word Begrung, я можу зробити висновок про те, що може бути мається на увазі Begrüßung. Тож я перетворюю його за всіма відомими кодируючими кодами та дивлюся, чи знайдений такий, який правильно перетворює.

Зазвичай існує кілька кодувань, які, здається, підходять.

Для довших файлів ви можете вирізати фрагмент замість перетворення сотень сторінок.

Так я б це назвав

encodingfinder.sh FILE Begrüßung

і тест сценарію, перетворюючи його на відомі кодування, яке з них виробляє "Begrüßung".

Щоб знайти таких персонажів, зазвичай допомагає менше, оскільки фанкі часто виділяються. З контексту зазвичай можна вивести потрібне слово для пошуку. Але ми не хочемо перевіряти за допомогою шестигранника, що це байт, а потім відвідувати нескінченні таблиці кодувань, щоб знайти нашого злочинця. :)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.