2009-01-25 6 views
15

Codierungsprobleme gehören zu den ein Thema, die mich am häufigsten während der Entwicklung gebissen haben. Jede Plattform besteht auf ihrer eigenen Kodierung, höchstwahrscheinlich sind einige Nicht-UTF-8-Standardeinstellungen im Spiel. (Ich arbeite normalerweise an Linux, Standard an UTF-8, meine Kollegen arbeiten meistens auf deutschem Windows, Standardisierung zu ISO-8859-1 oder ähnlicher Windows-Codepage)So testen Sie eine Anwendung für die korrekte Codierung (z. B. UTF-8)

Ich glaube, dass UTF-8 ein passender ist Standard für die Entwicklung einer i18nable-Anwendung. Nach meiner Erfahrung werden Encoding-Bugs jedoch in der Regel spät entdeckt (obwohl ich in Deutschland bin und einige Sonderzeichen haben, die zusammen mit ISO-8859-1 einige erkennbare Unterschiede liefern).

Ich glaube, dass diejenigen Entwickler mit einem vollständig Nicht-ASCII-Zeichensatz (oder diejenigen, die eine Sprache kennen, die einen solchen Zeichensatz verwendet) einen Vorsprung beim Bereitstellen von Testdaten bekommen. Aber es muss einen Weg geben, dies auch für den Rest von uns zu erleichtern.

Was [Technik | Werkzeug | Anreiz] Menschen verwenden hier? Wie bringen Sie Ihre Mitentwickler dazu, sich um diese Probleme zu kümmern? Wie testen Sie auf Einhaltung? Werden diese Tests manuell oder automatisch durchgeführt?

Hinzufügen eine mögliche Antwort im Voraus:

ich vor kurzem fliptitle.com entdeckt habe (sie eine einfache Möglichkeit bieten zu bekommen seltsame Zeichen geschrieben „uʍop ǝpısdn“ *) und ich habe vor, sie über die Verwendung leicht nachprüfbar zu schaffen UTF-8-Zeichenfolgen (da die meisten der dort verwendeten Zeichen an einer seltsamen binären Codierposition liegen), müssen jedoch systematischere Tests, Muster oder Techniken zur Gewährleistung der UTF-8-Kompatibilität/Verwendung vorhanden sein.

Hinweis: Obwohl es eine akzeptierte Antwort gibt, würde ich gerne mehr Techniken und Muster kennen, wenn es welche gibt. Bitte fügen Sie weitere Antworten hinzu, wenn Sie mehr Ideen haben. Und es war nicht einfach, nur eine Antwort zu wählen. Ich habe die regexp-Antwort für den am wenigsten erwarteten Winkel gewählt, um das Problem anzugehen, obwohl es auch Gründe geben würde, andere Antworten zu wählen. Schade, dass nur eine Antwort akzeptiert werden kann.

Vielen Dank für Ihre Eingabe.

*), das ist „upside down“ geschrieben „upside down“ für diejenigen, die nicht die Zeichen aufgrund von Problemen mit Schriftarten

+0

Vielen Dank für die (sehr geschätzt) Antworten bis jetzt - ich diese Frage offen halten, möchte für eine Weile für die Bewältigung des Problems möglichst viele Ideen zu sammeln. –

Antwort

5

Es gibt eine regular expression to test if a string is valid UTF-8:

$field =~ 
    m/\A(
    [\x09\x0A\x0D\x20-\x7E]   # ASCII 
    | [\xC2-\xDF][\x80-\xBF]    # non-overlong 2-byte 
    | \xE0[\xA0-\xBF][\x80-\xBF]  # excluding overlongs 
    | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte 
    | \xED[\x80-\x9F][\x80-\xBF]  # excluding surrogates 
    | \xF0[\x90-\xBF][\x80-\xBF]{2}  # planes 1-3 
    | [\xF1-\xF3][\x80-\xBF]{3}   # planes 4-15 
    | \xF4[\x80-\x8F][\x80-\xBF]{2}  # plane 16 
)*\z/x; 

Aber dies stellt nicht sicher, dass der Text tatsächlich UTF-8 ist.

Ein Beispiel: Die Bytefolge für den Buchstaben ö (U + 00F6) und die entsprechende UTF-8-Sequenz ist 0xC3B6.
Also, wenn Sie 0xC3B6 als Eingabe erhalten, können Sie sagen, dass es UTF-8 gültig ist. Aber man kann nicht sicher sagen, dass der Brief eingereicht wurde.
Dies ist weil sich vorstellen, dass nicht UTF-8 verwendet wurde, sondern stattdessen ISO 8859-1. Dort stellt die Folge 0xC3B6 das Zeichen à (0xC3) und ¶ (0xB6) dar.
So kann die Sequenz 0xC3B6 entweder ö mit UTF-8 oder à mit ISO 8859-1 darstellen (obwohl letztere eher ungewöhnlich ist).

Also am Ende ist es nur raten.

+0

Wow - das ist der am wenigsten erwartete Winkel um das Problem anzugehen. Ich bin beeindruckt. Außerdem gehört ¶ zu den am einfachsten als Codierungsfehler erkannten Zeichen. –

2

Der Ort ist ziemlich hart sehen.

Ich denke, dass Sie wirklich zwei Fragen stellen. Einer von ihnen, wie bringt man alle dazu, richtig an einer i8n-Anwendung zu arbeiten, ist meiner Meinung nach kein technisches, sondern ein Projektmanagementproblem. Wenn Sie möchten, dass Benutzer einen gemeinsamen Standard wie UTF-8 verwenden, müssen Sie dies einfach erzwingen. Tools werden helfen, aber die Leute müssen zuerst dazu aufgefordert werden.

Außerdem UTF-8 sagen, meiner Meinung nach ist der Weg zu gehen, ist es schwer, eine Antwort auf die Fragen über Werkzeuge zu geben. Es hängt wirklich von der Art des Projekts ab, das du machst. Wenn es sich beispielsweise um ein Java-Projekt handelt, über das Sie sprechen, dann ist es eine einfache Angelegenheit, die IDE richtig zu konfigurieren, um Dateien in UTF-8 zu verschlüsseln. Und um sicherzustellen, dass Ihre UTF-8-Lokalisierungen in externen Ressourcendateien enthalten sind.

Eine Sache, man kann sicherlich tun ist, um Unit-Tests zu machen, die Einhaltung zu überprüfen. Wenn Ihre lokalisierten Nachrichten/Labels in Ressourcendateien enthalten sind, ist es leicht zu überprüfen, ob sie richtig UTF-8-kodiert sind, denke ich.

+0

Sie haben Recht - es sind mehrere Fragen auf einmal. Hauptsächlich weil ich nicht herausgefunden habe, wie man das Problem wirklich angehen kann (außer einfach "keine Fehler zu machen" ...) Ich suche nach Werkzeugen für meine Toolbox, um in aktuellen und zukünftigen Projekten zu helfen. –

+1

plus - dein Tipp beschreibt die Situationen, die ich am besten erlebt habe: "es ist * einfach * leicht zu überprüfen ..." Ich mag das, es hat wirklich etwas Wahres daran ;-) –

3

Der wahre Unruhestifter mit Zeichencodierung ist ziemlich oft, dass es mehrere Fehler im Zusammenhang mit der Codierung gibt und dass aufgrund anderer Fehler ein falsches Verhalten eingeführt wurde. Ich kann nicht zählen, wie oft ich das gesehen habe.

Das Ziel ist wie immer, es an jedem einzelnen Ort richtig zu handhaben. Meistens können also einfache Unit Tests genügen, es müssen nicht einmal sehr komplexe Zeichensätze sein. Ich finde alle Fehler heraus, indem ich auf unseren nationalen Charakter "ø" teste, weil er in UTF-8 und den meisten anderen Zeichensätzen unterschiedlich abbildet.

Das Aggregat funktioniert gut, wenn alle Teile es richtig machen. Ich weiß, das klingt trivial, aber wenn es um Zeichensatz Probleme geht, hat es immer für mich funktioniert;)

+0

Das ist unser Firmengespräch - "Sobald du es richtig machst - Probleme verschwinden". :) Wie sind Sie dafür sorgen, dass die Tests für "ö" in UTF-8 nicht funktionieren, wenn es Tests für - sagen wir - "ö" in ISO-8859-1 - dh assertEquals ("ö", "ö") wird assertEquals („ö“, „ö“) - bildlich –

+1

Sie mit dem \ behaupten entkommen u Folge gegen die nicht-umgeschriebene Zeichen – krosenvold

1

In PHP verwenden wir die mb_ Funktionen wie mb_detect_encoding() und mb_convert_encoding(). Sie sind nicht perfekt, aber sie bringen uns 99,9% des Weges dorthin. Dann haben wir ein paar reguläre Ausdrücke, um funkige Charaktere auszuspionieren, die irgendwie hin und wieder herein kommen.

Wenn Sie international gehen, möchten Sie definitiv UTF-8 verwenden. Wir müssen noch die perfekte Lösung finden, um all unsere Daten in UTF-8 zu bekommen, und ich bin mir nicht sicher, ob es eine gibt. Du musst nur daran herumbasteln.

+0

mb_detect_encoding einen ähnlichen Ansatz wie die regexp von Gumbo obwohl besser lesbar zu versehen ist scheint - es sieht aus ähnlich heuristisch darin, dass die ¶ auch noch existieren würden, oder? Danke für Ihre Eingabe. –

11

Vielen Dank für fliptitle!

Auch ich versuche, einen richtigen Testplan zu erstellen, um sicherzustellen, dass eine Anwendung Unicode-Zeichenfolgen im gesamten System unterstützt.

Ich bin zweisprachig, aber in zwei Sprachen, die nur ISO-8859-1 verwenden. Daher habe ich mich angestrengt, herauszufinden, was eine "echte", "sinnvolle" Möglichkeit ist, die gesamte Bandbreite an Unicode-Möglichkeiten zu testen.

ich auf diese kam gerade:


Follow-Up Beitrag:

Nach ein paar Tests für meine Anwendung erarbeiten, wurde mir klar, dass ich zusammen gestellt hatte eine kleine Liste von codierten Werten, die für andere hilfreich sein könnten.

ich die folgenden internationalen Zeichenketten in meinem Test verwende:

(Anmerkung: hier kommt einige UTF-8 kodierten Text ... hoffentlich können Sie diese in Ihrem Browser sehen)

ユ ー ザ ー 別 サ イ ト
简体 中文
크로스 플랫폼 으로
מדורים מבוקשים
أفضل البحوث
Σὲ γνωρίζω ἀπὸ
Десятую Международную
แผ่นดิน ฮั่น เสื่อมโทรม แสน สังเวช
∮ E⋅da = Q, n → ∞, Σ f (i) = Π g (i)
Français langue étrangère
mañana olé

(End of UTF-8 fremder/nicht-englischer Text)

Allerdings stellte ich an verschiedenen Stellen während des Tests fest, dass es nicht ausreichte, nur Informationen darüber zu haben, wie die Zeichenketten in ihren jeweiligen Fremdalphabeten aussehen sollten. Ich musste auch die korrekten Unicode Codepunktzahlen und auch die korrekten hexadezimalen Werte für diese Strings in mindestens zwei Codierungen (UCS-2 und UTF-8) kennen.

ist hier die entsprechende Code-Punktnummerierung und Hex-Werte:

str = L"\u30E6\u30FC\u30B6\u30FC\u5225\u30B5\u30A4\u30C8"; // JAPAN 
// Little endian UTF-16/UCS-2: e6 30 fc 30 b6 30 fc 30 25 52 b5 30 a4 30 c8 30 00 00 
// Hex of UTF-8: e3 83 a6 e3 83 bc e3 82 b6 e3 83 bc e5 88 a5 e3 82 b5 e3 82 a4 e3 83 88 00 

str = L"\u7B80\u4F53\u4E2D\u6587"; // CHINA 
// Little endian UTF-16/UCS-2: 80 7b 53 4f 2d 4e 87 65 00 00 
// Hex of UTF-8: e7 ae 80 e4 bd 93 e4 b8 ad e6 96 87 00 

str = L"\uD06C\uB85C\uC2A4 \uD50C\uB7AB\uD3FC\uC73C\uB85C"; // KOREA 
// Little endian UTF-16/UCS-2: 6c d0 5c b8 a4 c2 20 00 0c d5 ab b7 fc d3 3c c7 5c b8 00 00 
// Hex of UTF-8: ed 81 ac eb a1 9c ec 8a a4 20 ed 94 8c eb 9e ab ed 8f bc ec 9c bc eb a1 9c 00 

str = L"\u05DE\u05D3\u05D5\u05E8\u05D9\u05DD \u05DE\u05D1\u05D5\u05E7\u05E9\u05D9\u05DD"; // ISRAEL 
// Little endian UTF-16/UCS-2: de 05 d3 05 d5 05 e8 05 d9 05 dd 05 20 00 de 05 d1 05 d5 05 e7 05 e9 05 d9 05 dd 05 00 00 
// Hex of UTF-8: d7 9e d7 93 d7 95 d7 a8 d7 99 d7 9d 20 d7 9e d7 91 d7 95 d7 a7 d7 a9 d7 99 d7 9d 00 

str = L"\u0623\u0641\u0636\u0644 \u0627\u0644\u0628\u062D\u0648\u062B"; // EGYPT 
// Little endian UTF-16/UCS-2: 23 06 41 06 36 06 44 06 20 00 27 06 44 06 28 06 2d 06 48 06 2b 06 00 00 
// Hex of UTF-8: d8 a3 d9 81 d8 b6 d9 84 20 d8 a7 d9 84 d8 a8 d8 ad d9 88 d8 ab 00 

str = L"\u03A3\u1F72 \u03B3\u03BD\u03C9\u03C1\u03AF\u03B6\u03C9 \u1F00\u03C0\u1F78"; // GREECE 
// Little endian UTF-16/UCS-2: a3 03 72 1f 20 00 b3 03 bd 03 c9 03 c1 03 af 03 b6 03 c9 03 20 00 00 
// Hex of UTF-8: ce a3 e1 bd b2 20 ce b3 ce bd cf 89 cf 81 ce af ce b6 cf 89 20 e1 bc 80 cf 80 e1 bd b8 00 

str = L"\u0414\u0435\u0441\u044F\u0442\u0443\u044E \u041C\u0435\u0436\u0434\u0443\u043D\u0430\u0440\u043E\u0434\u043D\u0443\u044E"; // RUSSIA 
// Little endian UTF-16/UCS-2: 14 04 35 04 41 04 4f 04 42 04 43 04 4e 04 20 00 1c 04 35 04 36 04 34 04 43 04 3d 04 30 04 40 04 3e 04 34 04 3d 04 43 04 4e 04 00 00 
// Hex of UTF-8: d0 94 d0 b5 d1 81 d1 8f d1 82 d1 83 d1 8e 20 d0 9c d0 b5 d0 b6 d0 b4 d1 83 d0 bd d0 b0 d1 80 d0 be d0 b4 d0 bd d1 83 d1 8e 00 

str = L"\u0E41\u0E1C\u0E48\u0E19\u0E14\u0E34\u0E19\u0E2E\u0E31\u0E48\u0E19\u0E40\u0E2A\u0E37\u0E48\u0E2D\u0E21\u0E42\u0E17\u0E23\u0E21\u0E41\u0E2A\u0E19\u0E2A\u0E31\u0E07\u0E40\u0E27\u0E0A"; // THAILAND 
// Little endian UTF-16/UCS-2: 41 0e 1c 0e 48 0e 19 0e 14 0e 34 0e 19 0e 2e 0e 31 0e 48 0e 19 0e 40 0e 2a 0e 37 0e 48 0e 2d 0e 21 0e 42 0e 17 0e 23 0e 21 0e 41 0e 2a 0e 19 0e 2a 0e 31 0e 07 0e 40 0e 27 0e 0a 0e 00 00 
// Hex of UTF-8: e0 b9 81 e0 b8 9c e0 b9 88 e0 b8 99 e0 b8 94 e0 b8 b4 e0 b8 99 e0 b8 ae e0 b8 b1 e0 b9 88 e0 b8 99 e0 b9 80 e0 b8 aa e0 b8 b7 e0 b9 88 e0 b8 ad e0 b8 a1 e0 b9 82 e0 b8 97 e0 b8 a3 e0 b8 a1 e0 b9 81 e0 b8 aa e0 b8 99 e0 b8 aa e0 b8 b1 e0 b8 87 e0 b9 80 e0 b8 a7 e0 b8 8a 00 

str = L"\u222E E\u22C5da = Q, n \u2192 \u221E, \u2211 f(i) = \u220F g(i)"; // MATHEMATICS 
// Little endian UTF-16/UCS-2: 2e 22 20 00 45 00 c5 22 64 00 61 00 20 00 3d 00 20 00 51 00 2c 00 20 00 20 00 6e 00 20 00 92 21 20 00 1e 22 2c 00 20 00 11 22 20 00 66 00 28 00 69 00 29 00 20 00 3d 00 20 00 0f 22 20 00 67 00 28 00 69 00 29 00 00 00 
// Hex of UTF-8: e2 88 ae 20 45 e2 8b 85 64 61 20 3d 20 51 2c 20 20 6e 20 e2 86 92 20 e2 88 9e 2c 20 e2 88 91 20 66 28 69 29 20 3d 20 e2 88 8f 20 67 28 69 29 00 

str = L"fran\u00E7ais langue \u00E9trang\u00E8re"; // FRANCE 
// Little endian UTF-16/UCS-2: 66 00 72 00 61 00 6e 00 e7 00 61 00 69 00 73 00 20 00 6c 00 61 00 6e 00 67 00 75 00 65 00 20 00 e9 00 74 00 72 00 61 00 6e 00 67 00 e8 00 72 00 65 00 00 00 
// Hex of UTF-8: 66 72 61 6e c3 a7 61 69 73 20 6c 61 6e 67 75 65 20 c3 a9 74 72 61 6e 67 c3 a8 72 65 00 

str = L"ma\u00F1ana ol\u00E9"; // SPAIN 
// Little endian UTF-16/UCS-2: 6d 00 61 00 f1 00 61 00 6e 00 61 00 20 00 6f 00 6c 00 e9 00 00 00 
// Hex of UTF-8: 6d 61 c3 b1 61 6e 61 20 6f 6c c3 a9 00 

Auch hier ein paar Bilder, die einige gemeinsame „mis-Renderings“ zeigen, dass in verschiedenen Editoren, obwohl die zugrunde liegenden passieren kann Bytes sind gut ausgebildete UTF8. Wenn Sie eines dieser Renderings sehen, bedeutet dies wahrscheinlich, dass Sie eine UTF8-Zeichenfolge korrekt erstellt haben, aber dass Ihr Editor/Viewer versucht, sie unter einer anderen Codierung als UTF8 zu interpretieren.

Sample Renderings Num. 1

Sample Renderings Num. 2

+0

Vielen Dank für diese Hinweise - ich sie irgendwie verpasst, wenn anfangs geschrieben, fand sie gerade jetzt –

Verwandte Themen