Wie erkenne ich eine fremde Figur?

Wie erkenne ich eine fremde Figur?

Ich versuche, ein seltsames Zeichen zu identifizieren, das ich in einer Datei gefunden habe, mit der ich arbeite:

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

Die Datei verwendet die ISO-8859-Kodierung und kann nicht in UTF-8 konvertiert werden:

$ 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

Meine Hauptfrage ist, wie ich die Ausgabe odhier interpretieren kann. Ich versuche zu verwendendiese SeiteDadurch kann ich zwischen verschiedenen Zeichendarstellungen übersetzen, aber es wird mir angezeigt, dass 005353als „Hex-Codepunkt“ Folgendes gilt, was nicht richtig zu sein scheint, und 0aebdass als „Hex-Codepunkt“ Folgendes gilt, was wiederum falsch zu sein scheint.

Wie kann ich also eine der drei Optionen ( 355, 005353oder 0aeb) verwenden, um herauszufinden, welches Zeichen sie darstellen sollen?

Und ja, ich habe es mit Unicode-Tools versucht, aber es scheint auch kein gültiges UTF-Zeichen zu sein:

$ 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

Wenn ich die Beschreibung des Unicode-Zeichens U+FFFD richtig verstehe, handelt es sich dabei gar nicht um ein echtes Zeichen, sondern um einen Platzhalter für ein beschädigtes Zeichen. Das macht Sinn, da die Datei eigentlich nicht UTF-8-kodiert ist.

Antwort1

Ihre Datei enthält zwei Bytes, EB und 0A in Hex. Es ist wahrscheinlich, dass die Datei einen Zeichensatz mit einem Byte pro Zeichen verwendet, wie zum BeispielISO-8859-1; in diesem Zeichensatz ist EB ë:

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

Andere Kandidaten wären δ inCodeseite 437, Ù inCodepage 850...

od -xDie Ausgabe von ist in diesem Fall aufgrund der Byte-Reihenfolge verwirrend; eine bessere Option ist -t x1die Verwendung einzelner Bytes:

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

od -xbildet ab od -t x2, liest jeweils zwei Bytes und gibt auf Little-Endian-Systemen die Bytes in umgekehrter Reihenfolge aus.

Wenn Sie auf eine Datei wie diese stoßen, die kein gültiges UTF-8 ist (oder keinen Sinn ergibt, wenn sie als UTF-8-Datei interpretiert wird), gibt es keine narrensichere Methode, ihre Kodierung (und ihren Zeichensatz) automatisch zu bestimmen. Der Kontext kann helfen: Wenn es sich um eine Datei handelt, die in den letzten Jahrzehnten auf einem westlichen PC erstellt wurde, besteht eine gute Chance, dass sie in ISO-8859-1, -15 (der Euro-Variante) oder Windows-1252 kodiert ist; wenn sie älter ist, sind CP-437 und CP-850 wahrscheinliche Kandidaten. Dateien aus osteuropäischen, russischen oder asiatischen Systemen würden andere Zeichensätze verwenden, über die ich nicht viel weiß. Dann gibt es EBCDIC... das iconv -lalle bekannten Zeichensätze auflistet iconv, und von dort aus können Sie nach dem Prinzip von Versuch und Irrtum weitermachen.

(Irgendwann konnte ich CP-437 und ATASCII größtenteils auswendig, das waren noch Zeiten.)

Antwort2

Beachten Sie, dass dies oddie Abkürzung fürOktaldump, also 005353sind die zwei Bytes als Oktalwort, od -xin 0aebHexadezimal als Wort und der eigentliche Inhalt Ihrer Datei sind die zwei Bytes ebund 0ain Hexadezimal, in dieser Reihenfolge.

Daher können beide 005353nicht 0aebeinfach als „Hex-Codepunkt“ interpretiert werden.

0aist ein Zeilenvorschub (LF) und ebhängt von Ihrer Kodierung ab. fileIch rate nur die Kodierung, es könnte alles Mögliche sein. Ohne weitere Informationen, woher die Datei stammt usw., wird es schwierig sein, das herauszufinden.

Antwort3

Es ist unmöglich, den Zeichensatz von Textdateien mit 100-prozentiger Genauigkeit zu erraten.

Tools wiechardet,Feuerfuchs,Datei -iWenn keine expliziten Zeichensatzinformationen definiert sind (z. B. wenn ein HTML im Kopf ein Meta-Zeichensatz = ... enthält, ist es einfacher), wird versucht, Heuristiken zu verwenden, die nicht so schlecht sind, wenn der Text groß genug ist.

Im Folgenden demonstriere ich die Zeichensatzerkennung mit chardet( pip install chardet/ apt-get install python-chardetfalls erforderlich).

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

Nachdem wir einen guten Zeichensatzkandidaten haben, können wir oder Ähnliches verwenden, iconvum recodeden Dateizeichensatz in Ihren „aktiven“ Zeichensatz (in meinem Fall UTF-8) zu ändern und zu sehen, ob die Antwort richtig war …

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

Einige Zeichensätze (wie ISO-8859-3, ISO-8859-1) haben viele Zeichen gemeinsam – manchmal ist es nicht einfach zu erkennen, ob wir den perfekten Zeichensatz gefunden haben …

Daher ist es sehr wichtig, dass dem relevanten Text Metadaten zugeordnet sind (z. B. XML).

Antwort4

#!/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 

Wenn ich eine Datei bekomme, die z.B. das Wort Begrüßung enthält, kann ich daraus schließen, dass Begrüßung gemeint sein könnte. Also konvertiere ich es nach allen bekannten Kodierungen und schaue, ob sich eine findet, die es richtig konvertiert.

Normalerweise gibt es mehrere Kodierungen, die zu passen scheinen.

Bei längeren Dateien schneiden Sie möglicherweise einen Ausschnitt aus, anstatt Hunderte von Seiten zu konvertieren.

Ich würde es also nennen

encodingfinder.sh FILE Begrüßung

und das Skript testet, ob durch Konvertierung mit den bekannten Kodierungen, welche davon eine "Begrüßung" erzeugen, eine Wirkung erzielt wird.

Um solche Zeichen zu finden, hilft normalerweise less, da auffällige Zeichen oft auffallen. Aus dem Kontext lässt sich das richtige Suchwort normalerweise ableiten. Wir möchten aber nicht mit einem Hexeditor nachschauen, welches Byte das ist, und dann endlose Tabellen mit Kodierungen durchforsten, um unseren Übeltäter zu finden. :)

verwandte Informationen