Ist es möglich, Benutzerdateien zuverlässig automatisch in Unicode zu decodieren? [C #]

8

Ich habe eine Webanwendung, mit der Benutzer ihren Inhalt zur Verarbeitung hochladen können. Die Verarbeitungs-Engine erwartet UTF8 (und ich erstelle XML aus mehreren Benutzerdateien), also muss ich sicherstellen, dass ich die hochgeladenen Dateien richtig dekodieren kann.

Da ich überrascht sein würde, wenn einer meiner Benutzer wüsste, dass seine Dateien sogar codiert sind, habe ich sehr wenig Hoffnung, dass er die Kodierung korrekt spezifizieren kann (Decoder) zu verwenden. Und so bleibt meiner Anwendung die Aufgabe, vor der Decodierung zu erkennen.

Das scheint so ein universelles Problem zu sein, ich bin überrascht, weder eine Rahmenfähigkeit noch ein allgemeines Rezept für die Lösung zu finden. Kann es sein, dass ich nicht mit aussagekräftigen Suchbegriffen suche?

Ich habe die BOM-Erkennung implementiert ( Ссылка ), aber ich bin mir nicht sicher, wie oft Dateien hochgeladen werden ohne BOM, um die Kodierung anzuzeigen, und das ist nicht nützlich für die meisten Nicht-UTF-Dateien.

Meine Fragen laufen auf:

  1. Ist die BOM-Erkennung für die überwiegende Mehrheit der Dateien ausreichend?
  2. Falls die BOM-Erkennung fehlschlägt, ist es möglich, verschiedene Dekodierer auszuprobieren und festzustellen, ob sie "gültig" sind ? (Meine Versuche zeigen an, dass die Antwort "Nein" ist.)
  3. Unter welchen Umständen schlägt eine "gültige" Datei mit dem C # -Encoder / Decoder-Framework fehl?
  4. Gibt es irgendwo ein Repository, das eine Vielzahl von Dateien mit verschiedenen Codierungen zum Testen enthält?
  5. Während ich speziell nach C # /. NET frage, würde ich gerne die Antwort auf Java, Python und andere Sprachen für das nächste Mal wissen, wenn ich das tun muss.

Bisher habe ich gefunden:

  • Eine "gültige" UTF-16-Datei mit Ctrl-S-Zeichen hat die Codierung von UTF-8 verursacht, um eine Ausnahme auszulösen (ungültiges Zeichen?) (Das war eine XML-Kodierungsausnahme.)
  • Decodierung einer gültigen UTF-16-Datei mit UTF-8 gelingt , gibt jedoch Text mit Nullzeichen. Huh?
  • Momentan erwarte ich nur UTF-8-, UTF-16- und wahrscheinlich ISO-8859-1-Dateien, aber ich möchte, dass die Lösung nach Möglichkeit erweiterbar ist.
  • Mein vorhandener Satz von Eingabedateien ist nicht annähernd breit genug, um alle Probleme aufzudecken, die bei Live-Dateien auftreten.
  • Obwohl die Dateien, die ich zu dekodieren versuche, "Text" sind, denke ich, dass sie oft mit Methoden erstellt werden, die Müllzeichen in den Dateien hinterlassen. Daher sind "gültige" Dateien möglicherweise nicht "rein". Oh Freude.

Danke.

    
NVRAM 22.02.2010, 20:58
quelle

5 Antworten

3

Es wird keinen absolut zuverlässigen Weg geben, aber Sie können vielleicht mit einigen Heuristiken ein "ziemlich gutes" Ergebnis erzielen.

  • Wenn die Daten mit einer Stückliste beginnen, verwenden Sie sie.
  • Wenn die Daten 0 Bytes enthalten, ist es wahrscheinlich utf-16 oder ucs-32. Sie können zwischen diesen und zwischen den Big-Endian- und Little-Endian-Varianten davon unterscheiden, indem Sie die Positionen der 0-Bytes betrachten
  • Wenn die Daten als utf-8 (ohne Fehler) dekodiert werden können, ist es sehr wahrscheinlich utf-8 (oder US-ASCII, aber dies ist eine Teilmenge von utf-8)
  • Wenn Sie als nächstes international werden möchten, ordnen Sie die Spracheinstellung des Browsers der wahrscheinlichsten Codierung für diese Sprache zu.
  • Nehmen wir schließlich ISO-8859-1
  • an

Ob "ziemlich gut" "gut genug" ist, hängt natürlich von Ihrer Anwendung ab. Wenn Sie sicher sein möchten, können Sie die Ergebnisse als Vorschau anzeigen und den Benutzer bestätigen lassen, dass die Daten korrekt aussehen. Wenn dies nicht der Fall ist, versuchen Sie die nächste wahrscheinliche Codierung, bis der Benutzer zufrieden ist.

Hinweis : Dieser Algorithmus funktioniert nicht, wenn die Daten ungültige Zeichen enthalten. Zum Beispiel wird ein einzelnes Müll-Byte in ansonsten gültigem utf-8 dazu führen, dass die utf-8-Decodierung fehlschlägt, wodurch der Algorithmus den falschen Pfad verlässt. Möglicherweise müssen Sie zusätzliche Maßnahmen ergreifen, um damit umzugehen. Wenn Sie beispielsweise möglichen Müll im Voraus identifizieren können, entfernen Sie ihn, bevor Sie versuchen, die Codierung zu ermitteln. (Es spielt keine Rolle, ob Sie zu aggressiv werden, sobald Sie die Kodierung festgelegt haben, können Sie die ursprünglichen nicht-entschlüsselten Daten dekodieren. Konfigurieren Sie die Dekoder einfach so, dass sie ungültige Zeichen ersetzen, anstatt eine Ausnahme auszulösen.) Oder zählen Sie Dekodierfehler und gewichten Sie diese entsprechend . Aber das hängt wahrscheinlich sehr von der Art Ihres Mülls ab, d. H. Welche Annahmen Sie treffen können.

    
oefe 22.02.2010 21:16
quelle
2

Haben Sie versucht, einen repräsentativen Querschnitt Ihrer Dateien vom Benutzer zu lesen, sie durch Ihr Programm zu führen, zu testen, Fehler zu korrigieren und weiterzumachen?

Ich habe festgestellt, dass File.ReadAllLines () in einer großen Bandbreite von Anwendungen ziemlich effektiv ist, ohne sich um alle Codierungen kümmern zu müssen. Es scheint ziemlich gut damit umzugehen.

Xmlreader () hat ziemlich gut gemacht, sobald ich herausgefunden habe, wie man es richtig benutzt.

Vielleicht könnten Sie einige spezifische Beispiele von Daten veröffentlichen und einige bessere Antworten erhalten.

    
No Refunds No Returns 22.02.2010 21:03
quelle
1

Dies ist ein bekanntes Problem. Sie können versuchen, was Internet Explorer tut. Dies ist ein netter Artikel im CodeProject, der die Lösung von Microsoft für das Problem beschreibt. Jedoch ist keine Lösung zu 100% korrekt, da alles auf Heuristiken basiert. Und es ist auch nicht sicher anzunehmen, dass eine Stückliste vorhanden sein wird.

    
kgiannakakis 22.02.2010 21:04
quelle
1

Sie können sich eine Python-basierte Lösung mit dem Namen chardet ansehen. Es ist ein Python-Port von Mozilla-Code. Obwohl Sie es möglicherweise nicht direkt verwenden können, ist seine Dokumentation lesenswert, genauso wie der ursprüngliche Mozilla-Artikel, auf den sie verweist.

    
John Machin 08.03.2010 01:35
quelle
0

Ich stieß auf ein ähnliches Problem. Ich brauchte ein Powershell-Skript, das herausfand, ob eine Datei im Text kodiert war (in einer gängigen Kodierung) oder nicht.

Es ist definitiv nicht erschöpfend, aber hier ist meine Lösung ...

PowerShell-Suchskript, das Binärdateien ignoriert

    
kervin 08.03.2010 01:41
quelle

Tags und Links