Sollte UTF-16 als schädlich angesehen werden?

432

Ich werde fragen, was wahrscheinlich eine ziemlich kontroverse Frage ist: "Sollte eine der beliebtesten Kodierungen, UTF-16, als schädlich angesehen werden?"

Warum stelle ich diese Frage?

Wie vielen Programmierern ist bekannt, dass UTF-16 tatsächlich eine Kodierung mit variabler Länge ist? Damit meine ich, dass es Codepunkte gibt, die als Ersatzpaare dargestellt werden und mehr als ein Element enthalten.

Ich weiß; Viele Anwendungen, Frameworks und APIs verwenden UTF-16, z. B. Javas String, C # -String, Win32-APIs, Qt-GUI-Bibliotheken, die ICU-Unicode-Bibliothek usw. Bei alledem treten jedoch viele grundlegende Fehler in der Verarbeitung auf von Zeichen aus BMP (Zeichen, die mit zwei UTF-16-Elementen codiert werden sollen).

Versuchen Sie beispielsweise, eines dieser Zeichen zu bearbeiten:

Je nachdem, welche Schriftarten Sie installiert haben, fehlen möglicherweise einige. Diese Zeichen befinden sich alle außerhalb des BMP (Basic Multilingual Plane). Wenn Sie diese Zeichen nicht sehen können, können Sie sie auch in der Unicode-Zeichenreferenz anzeigen .

Versuchen Sie beispielsweise, in Windows Dateinamen zu erstellen, die diese Zeichen enthalten. Versuchen Sie, diese Zeichen mit einem "Backspace" zu löschen, um zu sehen, wie sie sich in verschiedenen Anwendungen verhalten, die UTF-16 verwenden. Ich habe einige Tests gemacht und die Ergebnisse sind ziemlich schlecht:

  • Opera hat Probleme beim Bearbeiten (Löschen von 2 Drücken auf die Rücktaste erforderlich)
  • Notepad kann nicht richtig mit ihnen umgehen (Löschen von 2 Drücken auf die Rücktaste erforderlich)
  • Dateinamenbearbeitung in Fensterdialogen unterbrochen (Löschen erforderlich, 2 x Rücktaste drücken)
  • Alle QT3-Anwendungen können damit nicht umgehen - statt eines Symbols werden zwei leere Quadrate angezeigt .
  • Python codiert solche Zeichen falsch, wenn sie u'X'!=unicode('X','utf-16')auf einigen Plattformen direkt verwendet werden , wenn X ein Zeichen außerhalb von BMP ist.
  • Python 2.5-Unicodedaten können keine Eigenschaften für solche Zeichen abrufen, wenn Python mit UTF-16-Unicode-Zeichenfolgen kompiliert wird.
  • StackOverflow scheint diese Zeichen aus dem Text zu entfernen, wenn sie direkt als Unicode-Zeichen bearbeitet werden (diese Zeichen werden mit HTML-Unicode-Escapezeichen angezeigt).
  • WinForms TextBox generiert möglicherweise eine ungültige Zeichenfolge, wenn die Beschränkung auf MaxLength festgelegt ist.

Es scheint, dass solche Fehler in vielen Anwendungen, die UTF-16 verwenden, extrem leicht zu finden sind.

Also ... Glauben Sie, dass UTF-16 als schädlich angesehen werden sollte?

Artyom
quelle
64
Nicht wirklich richtig. Ich erkläre, wenn Sie "שָׁ" das zusammengesetzte Zeichen schreiben, das aus "ש", "ָ" und "ׁ" besteht, Vovels, dann ist das Entfernen von jedem von ihnen logisch, Sie entfernen einen Codepunkt, wenn Sie drücken. Rücktaste "und entferne alle Zeichen einschließlich Vovels, wenn du" Entf "drückst. Sie erzeugen jedoch niemals einen illegalen Textstatus - illegale Codepunkte. Daher ist die Situation, in der Sie die Rücktaste drücken und illegalen Text erhalten, falsch.
41
CiscoIPPhone: Wenn ein Fehler "mehrere Male, von vielen verschiedenen Personen" gemeldet wird und ein paar Jahre später ein Entwickler in einem Entwicklerblog schreibt, dass "Ob Sie es glauben oder nicht, das Verhalten ist größtenteils beabsichtigt!", Dann (um es auszudrücken) Ich neige dazu zu denken, dass es wahrscheinlich nicht die beste Designentscheidung ist, die jemals getroffen wurde. :-) Nur weil es absichtlich ist, heißt das nicht, dass es kein Fehler ist.
145
Guter Eintrag. UTF-16 ist in der Tat das "Schlimmste beider Welten": UTF8 hat eine variable Länge, deckt den gesamten Unicode-Code ab, erfordert einen Transformationsalgorithmus von und zu unformatierten Codepunkten, beschränkt sich auf ASCII und weist keine Endianness-Probleme auf. UTF32 hat eine feste Länge, erfordert keine Transformation, beansprucht jedoch mehr Speicherplatz und weist Endianness-Probleme auf. Soweit so gut, können Sie UTF32 intern und UTF8 für die Serialisierung verwenden. UTF16 hat jedoch keine Vorteile: Es ist endianabhängig, variabel lang, nimmt viel Platz in Anspruch und ist nicht ASCII-kompatibel. Der Aufwand für den korrekten Umgang mit UTF16 könnte besser für UTF8 aufgewendet werden.
Kerrek SB
26
@ Ian: UTF-8 hat NICHT die gleichen Einschränkungen wie UTF-8. Sie können in UTF-8 keine Ersatzzeichen verwenden. UTF-8 maskiert sich nicht als etwas, das es nicht ist, aber die meisten Programmierer, die UTF-16 verwenden, verwenden es falsch. Ich weiß. Ich habe sie immer wieder und immer wieder und immer wieder beobachtet.
tchrist
18
UTF-8 hat das Problem auch nicht, da es von allen als Codierung mit variabler Breite behandelt wird. Der Grund, warum UTF-16 das Problem hat, ist, dass jeder es wie eine Codierung mit fester Breite behandelt.
Christoffer Hammarström

Antworten:

340

Dies ist eine alte Antwort. Die neuesten Updates finden
Sie unter UTF-8 Everywhere .

Meinung: Ja, UTF-16 sollte als schädlich angesehen werden . Der Grund, warum es existiert, ist, dass es vor einiger Zeit einen Irrglauben gab, dass widechar das sein wird, was UCS-4 jetzt ist.

Trotz des "Anglozentrismus" von UTF-8 sollte es als die einzige nützliche Kodierung für Text angesehen werden. Man kann argumentieren, dass Quellcodes von Programmen, Webseiten und XML-Dateien, Betriebssystem-Dateinamen und anderen Computer-zu-Computer-Textschnittstellen niemals existieren sollten. Dabei ist Text nicht nur für den menschlichen Leser bestimmt.

Andererseits ist der UTF-8-Overhead ein geringer Preis, der erhebliche Vorteile bietet. Vorteile wie die Kompatibilität mit nicht bekanntem Code, mit dem nur Zeichenfolgen übergeben werden char*. Das ist eine großartige Sache. Es gibt nur wenige nützliche Zeichen, die in UTF-16 KÜRZER sind als in UTF-8.

Ich glaube, dass alle anderen Kodierungen irgendwann sterben werden. Dies bedeutet, dass MS-Windows, Java, ICU und Python es nicht mehr als Favorit verwenden. Nach langen Recherchen und Diskussionen verbieten die Entwicklungskonventionen in meinem Unternehmen die Verwendung von UTF-16, mit Ausnahme von OS-API-Aufrufen, und dies trotz der Bedeutung der Leistung in unseren Anwendungen und der Tatsache, dass wir Windows verwenden. Konvertierungsfunktionen wurden entwickelt, um immer angenommene UTF8-Dateien std::stringin native UTF-16 -Dateien zu konvertieren , die von Windows selbst nicht ordnungsgemäß unterstützt werden .

Für Leute, die sagen " Nutze, was gebraucht wird, wo es gebraucht wird ", ist es ein großer Vorteil, überall die gleiche Kodierung zu verwenden, und ich sehe keinen ausreichenden Grund, etwas anderes zu tun. Insbesondere halte ich das Hinzufügen wchar_tzu C ++ für einen Fehler, ebenso wie die Unicode-Ergänzungen zu C ++ 0x. Was jedoch von STL-Implementierungen verlangt werden muss, ist, dass jeder std::stringoder char*Parameter als Unicode-kompatibel angesehen wird.

Ich bin auch gegen den Ansatz " Nutze was du willst ". Ich sehe keinen Grund für eine solche Freiheit. Es gibt genug Verwirrung in Bezug auf das Thema Text, was zu all dieser kaputten Software führt. Nach alledem bin ich überzeugt, dass Programmierer endlich einen Konsens über UTF-8 als einen geeigneten Weg finden müssen. (Ich komme aus einem nicht-ascii-sprechenden Land und bin mit Windows aufgewachsen, daher würde ich zuletzt erwartet, UTF-16 aus religiösen Gründen anzugreifen.)

Ich möchte weitere Informationen darüber veröffentlichen, wie ich Text unter Windows verfasse und was ich allen anderen empfehle, um die Unicode-Korrektheit, die Benutzerfreundlichkeit und die bessere Multi-Plattform-Funktionalität des Codes während der Kompilierung zu überprüfen. Der Vorschlag unterscheidet sich erheblich von dem, was normalerweise für die ordnungsgemäße Verwendung von Unicode unter Windows empfohlen wird. Eine eingehende Untersuchung dieser Empfehlungen führte jedoch zu derselben Schlussfolgerung. Also los geht's:

  • Verwenden Sie keine wchar_toder std::wstringin einem anderen als benachbarten Punkt zu APIs akzeptieren UTF-16.
  • Verwenden Sie keine _T("")oder L""UTF-16-Literale (Diese sollten im Rahmen der UTF-16-Abschreibung aus dem Standard entfernt werden).
  • Verwenden Sie keine Typen, Funktionen oder deren Ableitungen, die für die _UNICODEKonstante empfindlich sind , wie z. B. LPTSTRoder CreateWindow().
  • Doch _UNICODEimmer definiert, zu vermeiden vorbei char*Strings WinAPI leise zusammengestellt bekommen
  • std::stringsund char*irgendwo im Programm gelten als UTF-8 (wenn nicht anders angegeben)
  • Alle meine Zeichenfolgen sind std::string, obwohl Sie Zeichen * oder Zeichenfolgenliteral übergeben können convert(const std::string &).
  • Verwenden Sie nur Win32-Funktionen, die widechars ( LPWSTR) akzeptieren . Niemals diejenigen, die akzeptieren LPTSTRoder LPSTR. Übergeben Sie die Parameter folgendermaßen:

    ::SetWindowTextW(Utils::convert(someStdString or "string litteral").c_str())
    

    (Die Richtlinie verwendet die folgenden Konvertierungsfunktionen.)

  • Mit MFC-Zeichenfolgen:

    CString someoneElse; // something that arrived from MFC. Converted as soon as possible, before passing any further away from the API call:
    
    std::string s = str(boost::format("Hello %s\n") % Convert(someoneElse));
    AfxMessageBox(MfcUtils::Convert(s), _T("Error"), MB_OK);
    
  • Arbeiten mit Dateien, Dateinamen und Fstream unter Windows:

    • Übergeben Sie niemals Argumente std::stringoder const char*Dateinamen an die fstreamFamilie. MSVC STL unterstützt keine UTF-8-Argumente, hat jedoch eine nicht standardmäßige Erweiterung, die wie folgt verwendet werden sollte:
    • std::stringArgumente konvertieren nach std::wstringmit Utils::Convert:

      std::ifstream ifs(Utils::Convert("hello"),
                        std::ios_base::in |
                        std::ios_base::binary);
      

      Wir müssen die Konvertierung manuell entfernen, wenn sich die Einstellung von MSVC zu fstreamÄnderungen ändert.

    • Dieser Code ist nicht plattformübergreifend und muss möglicherweise in Zukunft manuell geändert werden
    • fstreamWeitere Informationen finden Sie im Unicode-Recherche- / Diskussionsfall 4215.
    • Produzieren Sie niemals Textausgabedateien mit Nicht-UTF8-Inhalten
    • Vermeiden Sie die Verwendung fopen()aus RAII / OOD-Gründen. Verwenden Sie bei Bedarf die _wfopen()obigen WinAPI-Konventionen.

// For interface to win32 API functions
std::string convert(const std::wstring& str, unsigned int codePage /*= CP_UTF8*/)
{
    // Ask me for implementation..
    ...
}

std::wstring convert(const std::string& str, unsigned int codePage /*= CP_UTF8*/)
{
    // Ask me for implementation..
    ...
}

// Interface to MFC
std::string convert(const CString &mfcString)
{
#ifdef UNICODE
    return Utils::convert(std::wstring(mfcString.GetString()));
#else
    return mfcString.GetString();   // This branch is deprecated.
#endif
}

CString convert(const std::string &s)
{
#ifdef UNICODE
    return CString(Utils::convert(s).c_str());
#else
    Exceptions::Assert(false, "Unicode policy violation. See W569"); // This branch is deprecated as it does not support unicode
    return s.c_str();   
#endif
}
Pavel Radzivilovsky
quelle
39
Da kann ich nicht zustimmen Die Vorteile von utf16 gegenüber utf8 für viele asiatische Sprachen dominieren Ihre Argumentation. Es ist naiv zu hoffen, dass Japaner, Thailänder, Chinesen usw. diese Kodierung aufgeben werden. Die problematischen Konflikte zwischen Zeichensätzen treten auf, wenn die Zeichensätze, mit Ausnahme von Unterschieden, zumeist ähnlich zu sein scheinen. Ich schlage vor zu standardisieren: fest 7bit: iso-irv-170; 8-Bit-Variable: utf8; 16-Bit-Variable: utf16; 32bit behoben: ucs4.
82
@ Charles: danke für deine eingabe. Richtig, einige BMP-Zeichen sind in UTF-8 länger als in UTF-16. Aber seien wir ehrlich: Das Problem liegt nicht in Bytes, die chinesische BMP-Schriftzeichen benötigen, sondern in der Komplexität des Software-Designs, die entsteht. Wenn ein chinesischer Programmierer ohnehin Zeichen mit variabler Länge entwerfen muss, scheint UTF-8 im Vergleich zu anderen Variablen im System immer noch ein geringer Preis zu sein. Er könnte UTF-16 als Komprimierungsalgorithmus verwenden, wenn der Speicherplatz so wichtig ist, aber selbst dann ist er für LZ nicht geeignet, und nach LZ oder einer anderen generischen Komprimierung haben beide ungefähr dieselbe Größe und Entropie.
32
Was ich grundsätzlich sage, ist, dass die Vereinfachung durch One Encoding, das auch mit vorhandenen char * -Programmen kompatibel ist und heute für alles am beliebtesten ist, unvorstellbar ist. Es ist fast wie in guten alten "Klartext" Tagen. Möchten Sie eine Datei mit einem Namen öffnen? Es ist egal, was für einen Unicode Sie gerade ausführen usw. Ich schlage vor, wir, Entwickler, beschränken UTF-16 auf sehr spezielle Fälle schwerwiegender Optimierung, bei denen ein winziger Teil der Leistung mehrere Monate Arbeit wert ist.
17
Linux hatte eine spezielle Anforderung bei der internen Verwendung von UTF-8: Kompatibilität mit Unix. Windows brauchte das nicht, und als die Entwickler Unicode implementierten, fügten sie UCS-2-Versionen von fast allen Funktionen hinzu, die Text handhaben, und ließen die Multibyte-Funktionen einfach in UCS-2 konvertieren und die anderen aufrufen. Sie ersetzen später UCS-2 durch UTF-16. Linux hingegen hat sich an 8-Bit-Codierungen gehalten und daher UTF-8 verwendet, da dies in diesem Fall die richtige Wahl ist.
Mircea Chirea
34
@Pavel Radzivilovsky: Übrigens, Ihre Schriften über "Ich glaube, dass alle anderen Kodierungen irgendwann sterben werden. Dazu gehört, dass MS-Windows, Java, ICU und Python sie nicht mehr als ihre Favoriten verwenden." und "Insbesondere denke ich, dass das Hinzufügen von wchar_t zu C ++ ein Fehler war, ebenso wie die Unicode-Ergänzungen zu C ++ Ox." sind entweder ziemlich naiv oder sehr, sehr arrogant. Und das kommt von jemandem, der zu Hause mit Linux programmiert und mit den UTF-8-Zeichen zufrieden ist. Um es ganz klar auszudrücken: Es wird nicht passieren .
Paercebal
157

Unicode-Codepunkte sind keine Zeichen! Manchmal sind es nicht einmal Glyphen (visuelle Formen).

Einige Beispiele:

  • Codepunkte mit römischen Zahlen wie "ⅲ". (Ein einzelnes Zeichen, das wie "iii" aussieht.)
  • Akzentuierte Zeichen wie "á", die entweder als einzelnes kombiniertes Zeichen "\ u00e1" oder als getrenntes diakritisches Zeichen "\ u0061 \ u0301" dargestellt werden können.
  • Zeichen wie das griechische Sigma in Kleinbuchstaben, die unterschiedliche Formen für die Mitte ("σ") und das Ende ("ς") von Wortpositionen haben, die jedoch als Synonyme für die Suche betrachtet werden sollten.
  • Diskretionärer Unicode-Bindestrich U + 00AD, der je nach Kontext möglicherweise visuell angezeigt wird oder nicht und bei der semantischen Suche ignoriert wird.

Die einzige Möglichkeit, die Unicode-Bearbeitung zu optimieren, besteht darin , eine von einem Experten geschriebene Bibliothek zu verwenden oder selbst Experte zu werden und eine zu schreiben. Wenn Sie nur Codepunkte zählen, leben Sie in einem Zustand der Sünde.

Daniel Newby
quelle
19
Diese. Sehr viel das. UTF-16 kann Probleme verursachen, aber auch die Verwendung von UTF-32 kann (und wird) Ihnen Probleme bereiten.
bcat
11
Was ist ein Charakter? Sie können einen Codepunkt als Zeichen definieren und kommen damit ziemlich gut zurecht. Wenn Sie eine vom Benutzer sichtbare Glyphe meinen, ist das etwas anderes.
tchrist
7
@tchrist sicher für die Zuweisung von Speicherplatz, dass die Definition in Ordnung ist, aber für etwas anderes? Nicht so viel. Wenn Sie ein kombiniertes Zeichen als einziges Zeichen behandeln (z. B. für eine Lösch- oder N-Zeichen-Operation), werden Sie ein seltsames und falsches Verhalten feststellen. Wenn ein Codepunkt nur eine Bedeutung hat, wenn er mit mindestens einem anderen kombiniert ist, können Sie ihn auf keine vernünftige Weise alleine behandeln.
Voo
6
@ Pacerier, das ist zu spät für die Party, aber ich muss das kommentieren. Einige Sprachen haben sehr viele mögliche Kombinationen von Diakritika (vgl. Vietnamesisch, dh mệt đừ). Kombinationen statt eines Zeichens pro diakritischem Zeichen sind sehr hilfreich.
Asthasr
21
eine kleine Anmerkung zur Terminologie: Codepoints Sie entsprechen Unicode - Zeichen ; wovon Daniel hier spricht, sind vom Benutzer wahrgenommene Zeichen , die Unicode-Graphem-Clustern entsprechen
Christoph
54

Es gibt eine einfache Faustregel für die Verwendung von Unicode Transformation Form (UTF): - utf-8 für die Speicherung und Kommunikation - utf-16 für die Datenverarbeitung - Sie können utf-32 verwenden, wenn der größte Teil der von Ihnen verwendeten Plattform-API ist utf-32 (gebräuchlich in der UNIX-Welt).

Die meisten Systeme verwenden heute utf-16 (Windows, Mac OS, Java, .NET, ICU, Qt). Siehe auch dieses Dokument: http://unicode.org/notes/tn12/

Zurück zu "UTF-16 als schädlich" würde ich sagen: definitiv nicht.

Menschen, die sich vor Surrogaten fürchten (weil sie glauben, Unicode in eine Codierung variabler Länge umzuwandeln), verstehen die anderen (viel größeren) Komplexitäten nicht, die die Zuordnung zwischen Zeichen und einem Unicode-Codepunkt sehr komplex machen: das Kombinieren von Zeichen, Ligaturen und Variationsselektoren , Steuerzeichen usw.

Lesen Sie einfach diese Serie hier http://www.siao2.com/2009/06/29/9800913.aspx und sehen Sie, wie UTF-16 zu einem einfachen Problem wird.

Mihai Nita
quelle
26
Bitte fügen Sie einige Beispiele hinzu, in denen UTF-32 in der UNIX-Welt verbreitet ist!
Maxschlepzig
48
Nein, Sie möchten UTF-16 nicht für die Datenverarbeitung verwenden. Es ist ein Schmerz im Arsch. Es hat alle Nachteile von UTF-8, aber keinen seiner Vorteile. Sowohl UTF-8 als auch UTF-32 sind dem bösartigen Hack, der zuvor unter dem Namen Mrs UTF-16 bekannt war und dessen Mädchenname UCS-2 war, eindeutig überlegen.
tchrist
34
Ich habe gestern gerade einen Fehler in der equalsIgnoreCaseMethode der Java-Core-String-Klasse gefunden (auch andere in der String-Klasse), der niemals da gewesen wäre, wenn Java entweder UTF-8 oder UTF-32 verwendet hätte. Es gibt Millionen dieser schlafenden Bomben in jedem Code, der UTF-16 verwendet, und ich habe es satt und satt davon. UTF-16 ist eine bösartige Pocken, die unsere Software für immer und ewig mit heimtückischen Fehlern plagt. Es ist eindeutig schädlich und sollte veraltet und verboten werden.
Tchrist
7
@tchrist Wow, also eine nicht-ersatzbewusste Funktion (weil sie geschrieben wurde, als es keine gab, und leider so dokumentiert ist, dass es wahrscheinlich unmöglich ist, sie anzupassen - spezifiziert .toUpperCase (char)) wird zu einem falschen Verhalten führen? Sie wissen, dass eine UTF-32-Funktion mit einer veralteten Codepunktzuordnung dies nicht besser handhaben würde? Auch die gesamte Java-API handhabt Surrogate nicht besonders gut und die komplizierteren Punkte zu Unicode überhaupt nicht - und bei der späteren würde die verwendete Codierung überhaupt keine Rolle spielen.
Voo
8
-1: Ein Unbedingtes .Substring(1)in .NET ist ein triviales Beispiel für etwas, das die Unterstützung für alle Nicht-BMP-Unicode-Elemente beeinträchtigt. Alles , was UTF-16 verwendet, hat dieses Problem. Es ist zu einfach, es als Codierung mit fester Breite zu behandeln, und Sie sehen Probleme zu selten. Das macht es zu einer aktiv schädlichen Kodierung, wenn Sie Unicode unterstützen möchten.
Roman Starkov
43

Ja absolut.

Warum? Es hat mit dem Ausüben von Code zu tun .

Wenn Sie sich diese Codepoint-Verwendungsstatistiken für ein großes Korpus von Tom Christiansen ansehen, werden Sie feststellen, dass trans-8-Bit-BMP-Codepoints in mehreren Ordnungen verwendet werden, wenn die Magnitude höher ist als die von Nicht-BMP-Codepoints:

 2663710 U+002013 ‹–›  GC=Pd    EN DASH
 1065594 U+0000A0 ‹ ›  GC=Zs    NO-BREAK SPACE
 1009762 U+0000B1 ‹±›  GC=Sm    PLUS-MINUS SIGN
  784139 U+002212 ‹−›  GC=Sm    MINUS SIGN
  602377 U+002003 ‹ ›  GC=Zs    EM SPACE

 544 U+01D49E ‹𝒞›  GC=Lu    MATHEMATICAL SCRIPT CAPITAL C
 450 U+01D4AF ‹𝒯›  GC=Lu    MATHEMATICAL SCRIPT CAPITAL T
 385 U+01D4AE ‹𝒮›  GC=Lu    MATHEMATICAL SCRIPT CAPITAL S
 292 U+01D49F ‹𝒟›  GC=Lu    MATHEMATICAL SCRIPT CAPITAL D
 285 U+01D4B3 ‹𝒳›  GC=Lu    MATHEMATICAL SCRIPT CAPITAL X

Nehmen Sie das TDD-Sprichwort: "Ungetesteter Code ist fehlerhafter Code" und formulieren Sie es um als "nicht ausgeführter Code ist fehlerhafter Code". Überlegen Sie, wie oft Programmierer mit Nicht-BMP-Codepunkten umgehen müssen.

Fehler, die sich darauf beziehen, dass UTF-16 nicht als Codierung mit variabler Breite behandelt wird, werden mit größerer Wahrscheinlichkeit nicht bemerkt als die entsprechenden Fehler in UTF-8 . Einige Programmiersprachen garantieren immer noch nicht, dass Sie UTF-16 anstelle von UCS-2 erhalten, und einige sogenannte High-Level-Programmiersprachen bieten Zugriff auf Codeeinheiten anstelle von Code-Punkten (sogar C soll Ihnen Zugriff auf Code-Punkte gewähren) Codepunkte, wenn Sie verwenden wchar_t, unabhängig davon, was einige Plattformen tun können).

ninjalj
quelle
16
"Bugs, die sich darauf beziehen, UTF-16 nicht als Codierung mit variabler Breite zu behandeln, werden mit größerer Wahrscheinlichkeit nicht bemerkt als die entsprechenden Bugs in UTF-8." Dies ist der Kern des Problems und daher die richtige Antwort.
Sean McMillan
3
Genau. Wenn Ihr UTF-8-Handling kaputt ist, wird es sofort offensichtlich. Wenn Ihr UTF-8-Handling kaputt ist, werden Sie nur bemerken, wenn Sie ungewöhnliche Han-Zeichen oder mathematische Symbole eingeben.
Mechanische Schnecke
1
Sehr wahr, aber auf der anderen Seite, was sind Unit-Tests, wenn Sie auf das Glück angewiesen sind, in weniger häufigen Fällen Fehler zu finden?
Musiphil
@musiphil: Wann haben Sie das letzte Mal einen Komponententest für Nicht-BMP-Charaktere erstellt?
Ninjalj
1
Um auf meine frühere Aussage einzugehen: Selbst mit UTF-8 können Sie nicht sicher sein, dass Sie alle Fälle abgedeckt haben, nachdem Sie nur einige Arbeitsbeispiele gesehen haben. Dasselbe gilt für UTF-16: Sie müssen testen, ob Ihr Code sowohl mit Nicht-Surrogaten als auch mit Surrogaten funktioniert. (Jemand könnte sogar argumentieren, dass UTF-8 mindestens vier Hauptfälle hat, während UTF-16 nur zwei.)
musiphil
40

Ich würde vorschlagen, dass das Denken, dass UTF-16 als schädlich eingestuft werden könnte, bedeutet, dass Sie ein besseres Verständnis von Unicode erlangen müssen .

Lassen Sie mich näher darauf eingehen, da ich für die Darstellung meiner Meinung zu einer subjektiven Frage abgelehnt wurde. Was genau stört Sie an UTF-16? Würden Sie es vorziehen, wenn alles in UTF-8 kodiert wäre? UTF-7? Oder wie wäre es mit UCS-4? Natürlich sind bestimmte Anwendungen nicht dafür ausgelegt, jeden einzelnen Zeichencode zu verarbeiten - aber sie sind insbesondere in der heutigen globalen Informationsdomäne für die Kommunikation zwischen internationalen Grenzen erforderlich.

Aber wenn Sie der Meinung sind, dass UTF-16 als schädlich eingestuft werden sollte, weil es verwirrend ist oder nicht ordnungsgemäß implementiert werden kann (Unicode kann es sicherlich sein), welche Methode der Zeichencodierung wird dann als ungefährlich eingestuft?

EDIT: Um zu verdeutlichen: Warum betrachten unsachgemäße Implementierungen einer Norm eine Widerspiegelung der Qualität der Norm selbst? Wie andere später bemerkt haben, bedeutet nur, weil eine Anwendung ein Werkzeug unangemessen verwendet, nicht, dass das Werkzeug selbst defekt ist. Wenn dies der Fall wäre, könnten wir wahrscheinlich Dinge sagen wie "var Keyword als schädlich" oder "Threading als schädlich". Ich denke, die Frage verwechselt die Qualität und die Art des Standards mit den Schwierigkeiten, die viele Programmierer haben, wenn sie ihn richtig implementieren und verwenden, was meines Erachtens eher darauf zurückzuführen ist, dass sie nicht verstehen, wie Unicode funktioniert, als auf Unicode selbst.

patjbs
quelle
33
-1: Wie wäre es, einige von Artyoms Einwänden anzusprechen, anstatt ihn nur zu bevormunden?
8
Übrigens: Als ich anfing, diesen Artikel zu schreiben, wollte ich fast "Ist Joel auf Softeare-Artikel von Unicode schädlich" schreiben, weil es viele Fehler gibt. Beispiel: Die utf-8-Codierung nimmt bis zu 4 Zeichen und nicht 6 Zeichen auf. Außerdem wird nicht zwischen UCS-2 und UTF-16 unterschieden, die sich wirklich unterscheiden - und die Probleme verursachen, über die ich spreche.
32
Es sollte auch beachtet werden, dass, als Joel diesen Artikel schrieb, der UTF-8-Standard 6 Bytes und nicht 4 Bytes umfasste. RFC 3629 änderte den Standard einige Monate NACH dem Schreiben des Artikels in 4 Bytes. Wie fast alles im Internet lohnt es sich, aus mehreren Quellen zu lesen und das Alter Ihrer Quellen zu kennen. Der Link sollte nicht das "Ende aller sein alle" sein, sondern eher ein Ausgangspunkt.
7
Ich würde pic: utf-8 oder utf-32, die sind: variable Längenkodierung in fast allen Fällen (einschließlich BMP) oder feste Längenkodierung immer.
18
@iconiK: Sei nicht albern. UTF-16 ist absolut kein De-facto- Standard für die Textverarbeitung. Zeigen Sie mir eine Programmiersprache, die besser für die Textverarbeitung geeignet ist. Perl verwendet seit mehr als einem Jahrzehnt abstrakte Zeichen mit interner UTF-8-Darstellung. Aus diesem Grund verarbeitet jedes Perl-Programm automatisch sämtlichen Unicode, ohne dass der Benutzer ständig mit idiotischen Ersatzzeichen herumalbern muss. Die Länge einer Zeichenfolge entspricht der Anzahl der Codepunkte, nicht der Codeeinheiten. Alles andere ist bloße Dummheit, die das Rückwärts in Rückwärtskompatibilität versetzt.
tchrist
37

An der Utf-16-Codierung ist nichts falsch. Sprachen, die 16-Bit-Einheiten als Zeichen behandeln, sollten jedoch wahrscheinlich als schlecht gestaltet angesehen werden. Einen Typ mit dem Namen ' char' zu haben, der nicht immer ein Zeichen darstellt, ist ziemlich verwirrend. Da die meisten Entwickler erwarten, dass ein Zeichen-Typ einen Codepunkt oder ein Zeichen darstellt, wird wahrscheinlich ein Großteil des Codes beschädigt, wenn Zeichen außerhalb von BMP angezeigt werden.

Beachten Sie jedoch, dass die Verwendung von utf-32 nicht bedeutet, dass jeder 32-Bit-Codepunkt immer ein Zeichen darstellt. Aufgrund der Kombination von Zeichen kann ein tatsächliches Zeichen aus mehreren Codepunkten bestehen. Unicode ist niemals trivial.

BTW. Es gibt wahrscheinlich die gleiche Klasse von Fehlern mit Plattformen und Anwendungen, die 8-Bit-Zeichen erwarten, die mit Utf-8 gespeist werden.

JacquesB
quelle
12
In Javas Fall, wenn Sie sich die Zeitleiste ( java.com/en/javahistory/timeline.jsp ) ansehen , sehen Sie, dass die erste Entwicklung von String stattfand, als Unicode 16 Bit aufwies (es wurde 1996 geändert). Sie mussten sich auf die Fähigkeit konzentrieren, nicht mit BMP-Code-Punkten umzugehen, daher die Verwirrung.
Kathy Van Stone
10
@Kathy: Keine wirkliche Entschuldigung für C #. Im Allgemeinen stimme ich zu, dass es einen CodePointTyp geben sollte , der einen einzelnen Codepunkt (21 Bit) enthält, einen CodeUnitTyp, der eine einzelne Codeeinheit (16 Bit für UTF-16) enthält, und einen CharacterTyp, der idealerweise ein vollständiges Graphem unterstützen müsste. Aber das macht es funktional äquivalent zu einem String...
Joey
1
Diese Antwort ist fast zwei Jahre alt, aber ich kann nicht anders, als sie zu kommentieren. "Einen Typ namens 'char' zu haben, der nicht immer ein Zeichen darstellt, ist ziemlich verwirrend." Und dennoch wird es in C und dergleichen ständig verwendet, um ganzzahlige Daten darzustellen, die in einem einzelnen Byte gespeichert werden können.
JAB
Und ich habe eine Menge C-Code gesehen, der die Zeichenkodierung nicht richtig handhabt.
Dan04
1
C # hat eine andere Entschuldigung: Es wurde für Windows entwickelt und Windows wurde auf UCS-2 aufgebaut (es ist sehr ärgerlich, dass Windows-APIs auch heute noch UTF-8 nicht unterstützen können). Außerdem wollte Microsoft Java-Kompatibilität (.NET 1.0 hatte eine Java-Kompatibilitätsbibliothek, aber die Java-Unterstützung wurde sehr schnell eingestellt - ich vermute, dies liegt an der Klage von Sun gegen MS?)
Qwertie
20

Meine persönliche Entscheidung ist, immer UTF-8 zu verwenden. Es ist der Standard unter Linux für fast alles. Es ist abwärtskompatibel mit vielen älteren Apps. Der zusätzliche Speicherplatz für nicht-lateinische Zeichen ist im Vergleich zu den anderen UTF-Formaten sehr gering, und lateinische Zeichen sparen erheblich Platz. Im Internet stehen die lateinischen Sprachen an erster Stelle, und ich denke, sie werden es auf absehbare Zeit tun. Und um eines der Hauptargumente im ursprünglichen Beitrag anzusprechen: Fast jeder Programmierer weiß, dass UTF-8 manchmal Mehrbyte-Zeichen enthält. Nicht jeder geht damit richtig um, aber er ist sich normalerweise dessen bewusst, was für UTF-16 mehr ist als gesagt werden kann. Aber natürlich müssen Sie diejenige auswählen, die für Ihre Anwendung am besten geeignet ist. Deshalb gibt es in erster Linie mehr als einen.

rmeador
quelle
3
UTF-16 ist für alles in BMP einfacher, deshalb wird es so häufig verwendet. Aber ich bin auch ein Fan von UTF-8, es gibt auch keine Probleme mit der Bytereihenfolge, was sich positiv auswirkt.
Malcolm
2
Theoretisch ja. In der Praxis gibt es zum Beispiel UTF-16BE, was UTF-16 in Big Endian ohne Stückliste bedeutet. Dies ist nichts, was ich erfunden habe. Dies ist eine tatsächliche Codierung, die in ID3v2.4-Tags zulässig ist (ID3v2-Tags sind nicht gut, werden aber leider häufig verwendet). Und in solchen Fällen müssen Sie Endianness extern definieren, da der Text selbst keine Stückliste enthält. UTF-8 ist immer in eine Richtung geschrieben und es gibt kein solches Problem.
Malcolm
23
Nein, UTF-16 ist nicht einfacher. Es ist schwieriger Es führt Sie in die Irre und täuscht Sie, es sei eine feste Breite. All dieser Code ist kaputt und alles andere, weil man es erst bemerkt, wenn es zu spät ist. FALL IN PUNKT: Ich habe gestern einen weiteren dummen UTF-16-Fehler in den Java-Kernbibliotheken gefunden, diesmal in String.equalsIgnoreCase, der in der UCS-2-Fehlerkorrektur verblieben ist und daher bei 16/17 gültigen Unicode-Codepunkten fehlschlägt. Wie lange gibt es diesen Code schon? Keine Entschuldigung dafür, dass es fehlerhaft ist. UTF-16 führt zu Dummheit und einem Unfall, der darauf wartet, passiert zu werden. Führen Sie das Schreien von UTF-16 aus.
tchrist
3
@tchrist Man muss ein sehr ignoranter Entwickler sein, um nicht zu wissen, dass UTF-16 keine feste Länge hat. Wenn Sie mit Wikipedia beginnen, lesen Sie ganz oben Folgendes: "Es wird ein Ergebnis mit variabler Länge von einer oder zwei 16-Bit-Codeeinheiten pro Codepunkt erzeugt". Die Unicode-FAQ sagt dasselbe: unicode.org/faq//utf_bom.html#utf16-1 . Ich weiß nicht, wie UTF-16 jemanden täuschen kann, wenn überall geschrieben steht, dass es eine variable Länge hat. Die Methode wurde nie für UTF-16 entwickelt und sollte nicht so einfach als Unicode betrachtet werden.
Malcolm,
2
@tchrist Hast du eine Quelle für deine Statistiken? Obwohl gute Programmierer rar sind, finde ich das gut, weil wir wertvoller werden. :) Bei den Java-APIs werden char-basierte Teile möglicherweise veraltet, dies ist jedoch keine Garantie dafür, dass sie nicht verwendet werden. Und sie werden aus Kompatibilitätsgründen definitiv nicht entfernt.
Malcolm
18

Nun, es gibt eine Codierung, die Symbole mit fester Größe verwendet. Ich meine mit Sicherheit UTF-32. Aber 4 Bytes für jedes Symbol bedeuten zu viel Platzverschwendung. Warum sollten wir es in alltäglichen Situationen verwenden?

Meiner Meinung nach ergeben sich die meisten Probleme aus der Tatsache, dass einige Software hinter dem Unicode-Standard zurückblieb, die Situation jedoch nicht schnell korrigierte. Opera, Windows, Python, Qt - alle erschienen, bevor UTF-16 allgemein bekannt wurde oder überhaupt entstand. Ich kann jedoch bestätigen, dass es in Opera, Windows Explorer und Notepad keine Probleme mit Zeichen außerhalb von BMP mehr gibt (zumindest auf meinem PC). Wenn Programme jedoch keine Ersatzpaare erkennen, verwenden sie kein UTF-16. Welche Probleme auch immer beim Umgang mit solchen Programmen auftreten mögen, sie haben nichts mit UTF-16 selbst zu tun.

Ich denke jedoch, dass die Probleme von Legacy-Software mit nur BMP-Unterstützung etwas übertrieben sind. Zeichen außerhalb von BMP sind nur in ganz bestimmten Fällen und Bereichen anzutreffen. Laut der offiziellen Unicode-FAQ "sollte die Inzidenz von Ersatzpaaren selbst in ostasiatischen Texten deutlich unter 1% des gesamten Textspeichers liegen". Natürlich sollten Zeichen außerhalb von BMP nicht vernachlässigt werden, da ein Programm ansonsten nicht Unicode-konform ist, aber die meisten Programme sind nicht für die Arbeit mit Texten gedacht, die solche Zeichen enthalten. Deshalb ist es unangenehm, aber keine Katastrophe, wenn sie es nicht unterstützen.

Betrachten wir nun die Alternative. Wenn UTF-16 nicht vorhanden wäre, hätten wir keine Codierung, die für Nicht-ASCII-Text gut geeignet wäre, und die gesamte für UCS-2 erstellte Software müsste komplett neu gestaltet werden, um Unicode-kompatibel zu bleiben. Letzteres würde die Übernahme von Unicode höchstwahrscheinlich nur verlangsamen. Wir wären auch nicht in der Lage gewesen, die Kompatibilität mit Text in UCS-2 aufrechtzuerhalten, wie es UTF-8 in Bezug auf ASCII tut.

Was spricht nun gegen die Kodierung selbst, abgesehen von all den alten Problemen? Ich bezweifle wirklich, dass Entwickler heutzutage nicht wissen, dass UTF-16 eine variable Länge hat. Es wird überall geschrieben, wo Wikipedia zum Einsatz kommt. UTF-16 ist viel weniger schwierig zu analysieren als UTF-8, wenn jemand auf die Komplexität als mögliches Problem hingewiesen hat. Es ist auch falsch zu glauben, dass es einfach ist, die String-Länge nur in UTF-16 zu bestimmen. Wenn Sie UTF-8 oder UTF-32 verwenden, sollten Sie dennoch wissen, dass ein Unicode-Codepunkt nicht unbedingt ein Zeichen bedeutet. Abgesehen davon glaube ich nicht, dass etwas Wesentliches gegen die Kodierung spricht.

Daher denke ich nicht, dass die Codierung selbst als schädlich angesehen werden sollte. UTF-16 ist ein Kompromiss zwischen Einfachheit und Kompaktheit, und es schadet nicht, das , was benötigt wird, dort zu verwenden, wo es benötigt wird . In einigen Fällen müssen Sie mit ASCII kompatibel bleiben, und Sie benötigen UTF-8. In einigen Fällen möchten Sie mit Han-Ideogrammen arbeiten und mit UTF-16 Platz sparen. Längencodierung. Verwenden Sie, was angemessener ist, machen Sie es einfach richtig.

Malcolm
quelle
21
Das ist eine eher blinzelnde, anglozentrische Ansicht, Malcolm. Fast auf Augenhöhe mit "ASCII ist gut genug für die USA - der Rest der Welt sollte zu uns passen".
Jonathan Leffler
28
Eigentlich komme ich aus Russland und habe ständig mit Kyrillik zu tun (einschließlich meiner eigenen Programme), daher glaube ich nicht, dass ich eine anglozentrische Sichtweise habe. :) ASCII zu erwähnen ist nicht ganz angemessen, da es kein Unicode ist und keine bestimmten Zeichen unterstützt. UTF-8, UTF-16, UTF-32 unterstützen dieselben internationalen Zeichensätze, sie sind nur für die Verwendung in bestimmten Bereichen vorgesehen. Und das ist genau mein Punkt: Wenn Sie hauptsächlich Englisch verwenden, verwenden Sie UTF-8, wenn Sie hauptsächlich Kyrillisch verwenden, verwenden Sie UTF-16, wenn Sie alte Sprachen verwenden, verwenden Sie UTF-32. Ziemlich einfach.
Malcolm
16
"Nicht wahr, asiatische Skripte wie Japanisch, Chinesisch oder Arabisch gehören auch zu BMP. BMP selbst ist tatsächlich sehr groß und sicherlich groß genug, um alle heutzutage verwendeten Skripte aufzunehmen." Das ist alles so falsch. BMP enthält 0xFFFF-Zeichen (65536). Chinesisch allein hat mehr als das. Chinesische Standards (GB 18030) haben mehr als das. Unicode 5.1 hat bereits mehr als 100.000 Zeichen zugewiesen.
12
@Marcolm: "BMP selbst ist tatsächlich sehr groß und sicherlich groß genug, um alle heute verwendeten Skripte einzuschließen." Nicht wahr. Zu diesem Zeitpunkt hat Unicode bereits ca. 100 KB Zeichen zugewiesen, womit weit mehr als in BMP möglich sind. Es gibt große Mengen chinesischer Schriftzeichen außerhalb von BMP. Einige von ihnen werden vom GB-18030 (obligatorischer chinesischer Standard) benötigt. Andere sind nach (nicht obligatorischen) japanischen und koreanischen Standards erforderlich. Wenn Sie also versuchen, auf diesen Märkten etwas zu verkaufen, brauchen Sie mehr als nur BMP-Unterstützung.
8
Alles, was UTF-16 verwendet, aber nur enge BMP-Zeichen verarbeiten kann, verwendet UTF-16 nicht. Es ist fehlerhaft und kaputt. Die Prämisse des OP ist solide: UTF-16 ist schädlich, weil es naive Leute dazu bringt, gebrochenen Code zu schreiben. Entweder können Sie mit Unicode-Text umgehen oder nicht. Wenn nicht, wählen Sie eine Teilmenge aus, die genauso dumm ist wie die reine ASCII-Textverarbeitung.
Tchrist
16

Die jahrelange Internationalisierung von Windows, insbesondere in ostasiatischen Sprachen, hat mich vielleicht verfälscht, aber ich neige zu UTF-16 für programminterne Darstellungen von Zeichenfolgen und UTF-8 für die Netzwerk- oder Dateispeicherung von Nur-Text-ähnlichen Dokumenten. In der Regel kann UTF-16 unter Windows jedoch schneller verarbeitet werden. Dies ist der Hauptvorteil der Verwendung von UTF-16 unter Windows.

Der Sprung auf UTF-16 hat die Angemessenheit durchschnittlicher Produkte, die internationalen Text verarbeiten, dramatisch verbessert. Es gibt nur wenige enge Fälle, in denen die Ersatzpaare berücksichtigt werden müssen (im Grunde genommen Deletionen, Insertionen und Zeilenumbrüche), und der Durchschnittsfall ist meistens ein gerader Durchgang. Und im Gegensatz zu früheren Codierungen wie JIS-Varianten beschränkt UTF-16 Ersatzpaare auf einen sehr engen Bereich, sodass die Überprüfung sehr schnell ist und vorwärts und rückwärts funktioniert.

Zugegeben, es ist auch in korrekt codiertem UTF-8 ungefähr so ​​schnell. Es gibt aber auch viele fehlerhafte UTF-8-Anwendungen, die Ersatzpaare fälschlicherweise als zwei UTF-8-Sequenzen codieren. UTF-8 garantiert also auch keine Rettung.

IE verarbeitet Ersatzpaare seit etwa 2000 recht gut, obwohl sie normalerweise von UTF-8-Seiten in eine interne UTF-16-Darstellung konvertiert werden. Ich bin mir ziemlich sicher, dass Firefox es auch richtig gemacht hat, daher ist es mir egal, was Opera macht.

UTF-32 (auch bekannt als UCS4) ist für die meisten Anwendungen sinnlos, da es so platzraubend ist, dass es so gut wie kein Anfänger ist.

JasonTrue
quelle
6
Ich habe Ihren Kommentar zu UTF-8 und Ersatzpaaren nicht ganz verstanden. Ersatzpaare sind nur ein Konzept, das in der UTF-16-Codierung Sinn macht, oder? Code, der direkt von der UTF-16-Codierung in die UTF-8-Codierung konvertiert, kann möglicherweise falsch angezeigt werden. In diesem Fall wird die UTF-16-Codierung falsch gelesen und die UTF-8-Codierung nicht geschrieben. Ist das richtig?
Craig McQueen
11
Jason spricht von Software, die absichtlich UTF-8 auf diese Weise implementiert: Erstellen Sie ein Ersatzpaar, und codieren Sie dann jede Hälfte mit UTF-8 separat. Der korrekte Name für diese Codierung lautet CESU-8, aber Oracle (z. B.) stellt ihn als UTF-8 falsch dar. Java verwendet ein ähnliches Schema für die Objektserialisierung, ist jedoch eindeutig als "Geändertes UTF-8" und nur für den internen Gebrauch dokumentiert. (Wenn wir die Leute nur dazu bringen könnten, diese Dokumentation ZU LESEN und die Verwendung von DataInputStream # readUTF () und DataOutputStream # writeUTF () unangemessen zu beenden ...)
AFAIK, UTF-32 ist immer noch eine Kodierung mit variabler Länge und ungleich UCS4, einem spezifischen Bereich von Codepunkten.
Eonil
@Eonil, UTF-32 kann nur dann von UCS4 unterschieden werden, wenn es einen Unicode-Standard gibt, der so etwas wie UCS5 oder höher enthält.
JasonTrue
@JasonTrue Trotzdem sind nur die Ergebnisse zufällig gleich, nicht von der Konstruktion her garantiert. Dasselbe geschah bei der 32-Bit-Speicheradressierung Y2K, UTF16 / UCS2. Oder haben wir irgendeine Garantie für diese Gleichheit? Wenn ja, würde ich das gerne nutzen. Aber ich möchte keinen möglichen Code schreiben , der kaputt geht . Ich schreibe einen Code auf Zeichenebene, und das Fehlen einer garantierten Transcodierungsmethode zwischen UTF <-> -Code-Punkten nervt mich sehr.
Eonil
16

UTF-8 ist definitiv der richtige Weg, möglicherweise zusammen mit UTF-32 für den internen Gebrauch in Algorithmen, die einen Hochleistungs-Direktzugriff benötigen (aber das Kombinieren von Zeichen ignorieren).

Sowohl UTF-16 als auch UTF-32 (sowie ihre LE / BE-Varianten) leiden unter Endianess-Problemen, daher sollten sie niemals extern verwendet werden.

Tronic
quelle
9
Auch mit UTF-8 ist ein ständiger Direktzugriff möglich. Verwenden Sie nur Codeeinheiten anstelle von Codepunkten. Möglicherweise benötigen Sie einen echten Zugriff auf zufällige Codepunkte, aber ich habe noch nie einen Anwendungsfall gesehen, und Sie möchten wahrscheinlich stattdessen einen zufälligen Zugriff auf Graphemcluster.
15

UTF-16? definitiv schädlich. Nur mein Salzkorn hier, aber es gibt genau drei akzeptable Kodierungen für Text in einem Programm:

  • ASCII: Wenn es um Low-Level-Dinge geht (zB Mikrocontroller), die sich nichts Besseres leisten können
  • UTF8: Speicherung in Medien mit fester Breite, z. B. Dateien
  • Ganzzahlige Codepunkte ("CP"?): Ein Array mit den größten Ganzzahlen, die für Ihre Programmiersprache und Plattform geeignet sind (ASCII-Zerfall im Grenzfall niedriger Resourcen). Sollte int32 auf älteren Computern und int64 auf allen mit 64-Bit-Adressierung sein.

  • Offensichtlich verwenden Schnittstellen zu Legacy-Code die Kodierung, die erforderlich ist, damit der alte Code richtig funktioniert.

David X.
quelle
4
@simon buchan, der U+10ffffmax geht aus dem fenster, wenn (nicht wenn) ihnen die codepoints ausgehen . Das heißt, die Verwendung von int32 auf einem p64-System für Geschwindigkeit ist wahrscheinlich sicher, da ich bezweifle, dass sie überschritten werden, U+ffffffffbevor Sie gezwungen sind, Ihren Code für 128-Bit-Systeme um 2050 umzuschreiben ist bequem "im Gegensatz zu" größten verfügbaren "(die wahrscheinlich int256 oder Bignums oder etwas sein würde).
David X
1
@ David: Unicode 5.2 codiert 107.361 Codepunkte. Es gibt 867.169 nicht verwendete Codepunkte. "Wann" ist nur albern. Ein Unicode-Codepunkt ist definiert als eine Zahl von 0 bis 0x10FFFF, eine Eigenschaft, von der UTF-16 abhängt. (Auch 2050 scheint eine Schätzung für 128-Bit-Systeme viel zu niedrig, wenn ein 64-Bit-System das gesamte Internet in seinem Adressraum halten kann.)
3
@David: Ihr "Wann" bezog sich auf das Ende der Unicode-Codepunkte, nicht auf einen 128-Bit-Switch, der in den nächsten Jahrhunderten verfügbar sein wird. Im Gegensatz zum Speicher gibt es kein exponentielles Wachstum der Zeichen. Daher hat das Unicode-Konsortium ausdrücklich garantiert, dass sie keinen Codepunkt mehr zuweisen U+10FFFF. Das ist wirklich ein jene Situationen , wenn 21 Bits sind genug für jeden.
10
@ Simon Buchan: Zumindest bis zum ersten Kontakt. :)
3
Unicode verwendet, um sicherzustellen, dass es keine Codepunkte über U + FFFF geben würde.
Shannon Severance
13

Unicode definiert Codepunkte bis zu 0x10FFFF (1.114.112 Codes). Alle Anwendungen, die in einer mehrsprachigen Umgebung mit Zeichenfolgen, Dateinamen usw. ausgeführt werden, sollten dies korrekt handhaben.

Utf-16 : deckt nur 1.112.064 Codes ab. Diese am Ende von Unicode stammen zwar aus den Ebenen 15-16 (Private Use Area). Es kann in Zukunft nicht weiter wachsen, außer wenn das Utf-16- Konzept gebrochen wird .

Utf-8 : deckt theoretisch 2.216.757.376 Codes ab. Der aktuelle Bereich von Unicode- Codes kann durch eine Sequenz von maximal 4 Bytes dargestellt werden. Es hat keine Probleme mit der Bytereihenfolge , es ist "kompatibel" mit ASCII.

Utf-32 : deckt theoretisch 2 ^ 32 = 4.294.967.296 Codes ab. Derzeit ist es nicht mit variabler Länge codiert und wird wahrscheinlich nicht in der Zukunft sein.

Diese Tatsachen sind selbsterklärend. Ich verstehe nicht, dass ich den allgemeinen Gebrauch von Utf-16 befürworte . Es ist in variabler Länge codiert (kann nicht über den Index aufgerufen werden), es hat Probleme, den gesamten Unicode- Bereich abzudecken , auch wenn die Bytereihenfolge noch verarbeitet werden muss usw. Ich sehe keinen Vorteil, außer dass es nativ in Windows und einigen anderen Betriebssystemen verwendet wird andere Plätze. Auch wenn es beim Schreiben von Code für mehrere Plattformen wahrscheinlich besser ist, Utf-8 nativ zu verwenden und Konvertierungen nur an den Endpunkten in plattformabhängiger Weise durchzuführen (wie bereits vorgeschlagen). Wenn ein direkter Zugriff per Index erforderlich ist und der Speicher kein Problem darstellt, sollte Utf-32 verwendet werden.

Das Hauptproblem besteht darin, dass viele Programmierer, die sich mit Windows Unicode = Utf-16 beschäftigen , nicht einmal die Tatsache kennen oder ignorieren, dass es sich um eine variable Länge handelt.

Die Art und Weise, wie es normalerweise in * nix- Plattformen ist, ist ziemlich gut. C-Strings (char *) werden als Utf-8- codierte, breite c-Strings (wchar_t *) als Utf-32 interpretiert .

Pavel Machyniak
quelle
7
Hinweis: UTF-16 deckt alle Unicode-Bereiche ab, da das Unicode-Konsortium entschieden hat, dass 10FFFF der TOP-Bereich von Unicode ist und UTF-8 mit einer maximalen Länge von 4 Bytes und einem explizit ausgeschlossenen Bereich von 0xD800-0xDFFF definiert. Dieser Bereich wird für die Erstellung von verwendet Ersatzpaare. Somit kann jeder gültige Unicode-Text mit jeder dieser Codierungen dargestellt werden. Auch über das Wachsen in die Zukunft. Es scheint nicht, dass 1 Million Codepunkte in naher Zukunft nicht ausreichen würden.
7
@Kerrek: Falsch: UCS-2 ist keine gültige Unicode-Codierung. Alle UTF- * -Codierungen können per Definition jeden Unicode-Codepunkt darstellen, der für den Austausch zulässig ist. UCS-2 kann weit weniger als das darstellen, plus ein paar mehr. Wiederholen: UCS-2 ist keine gültige Unicode-Codierung, alles andere als ASCII.
tchrist
1
"Ich verstehe nicht, dass ich die allgemeine Verwendung von Utf-8 befürworte . Es ist in variabler Länge codiert (kann nicht über den Index aufgerufen werden)"
Ian Boyd
9
@ Ian Boyd, die Notwendigkeit, in einem zufälligen Zugriffsmuster auf die einzelnen Zeichen eines Strings zuzugreifen, ist unglaublich hoch. Es ist ungefähr so ​​üblich, wie die Diagonale einer Zeichenmatrix berechnen zu wollen, was sehr selten ist. Zeichenfolgen werden praktisch immer nacheinander verarbeitet, und da der Zugriff auf UTF-8-Zeichen N + 1 bei UTF-8-Zeichen N 0 (1) ist, gibt es kein Problem. Der zufällige Zugriff auf Zeichenfolgen ist erstaunlich selten. Ob es sich für Sie lohnt, auf UTF-32 anstatt auf UTF-8 zuzugreifen, ist Ihre Meinung, aber für mich ist es insgesamt kein Problem.
tchrist
2
@tchrist, ich gebe dir zu, dass Strings praktisch immer sequentiell abgearbeitet werden, wenn du die Reverse-Iteration als "sequentiell" einfügst und damit einen weiteren Vergleich des hinteren Endes eines Strings mit einem bekannten String ausführst. Zwei sehr häufige Szenarien sind das Abschneiden von Leerzeichen am Ende von Zeichenfolgen und das Überprüfen der Dateierweiterung am Ende eines Pfads.
Andy Dent
11

Fügen Sie dies der Liste hinzu:

Das vorgestellte Szenario ist einfach (noch einfacher, als ich es hier vorstellen werde): 1.Eine WinForms-TextBox befindet sich in einem Formular, leer. Die maximale Länge ist auf 20 festgelegt .

2. Der Benutzer gibt Text in die TextBox ein oder fügt möglicherweise Text ein.

3. Unabhängig davon, was Sie in die TextBox eingeben oder einfügen, ist die Anzahl auf 20 begrenzt. Bei Text, der über die 20 hinausgeht, wird jedoch ein Piepton ausgegeben (hier YMMV; ich habe mein Klangschema geändert, um diesen Effekt zu erzielen!).

4.Das kleine Textpaket wird dann an einen anderen Ort gesendet, um ein aufregendes Abenteuer zu beginnen.

Dies ist ein einfaches Szenario, und jeder kann es in seiner Freizeit aufschreiben. Ich habe es selbst in mehreren Programmiersprachen mit WinForms geschrieben, weil ich gelangweilt war und es noch nie zuvor ausprobiert hatte. Und mit Text in mehreren aktuellen Sprachen, weil ich auf diese Weise verkabelt bin und mehr Tastaturlayouts habe als irgendjemand im ganzen verrückten Universum.

Ich habe sogar die Form Magic Carpet Ride genannt , um die Langeweile zu lindern.

Das hat nicht funktioniert, was es wert ist.

Also habe ich stattdessen die folgenden 20 Zeichen in mein Magic Carpet Ride- Formular eingegeben :

0123401234012340123 𠀀

Oh oh.

Das letzte Zeichen ist U + 20000, das erste Extension B-Ideogramm von Unicode (auch bekannt als U + d840 U + dc00).

Bildbeschreibung hier eingeben

Und jetzt haben wir ein Ballspiel.

Denn wenn TextBox.MaxLength spricht über

Ruft die maximale Anzahl von Zeichen ab, die manuell in das Textfeld eingegeben werden können, oder legt diese fest.

Was es wirklich bedeutet, ist

Ruft die maximale Anzahl von UTF-16-LE-Codeeinheiten ab, die manuell in das Textfeld eingegeben werden können, und schneidet den lebenden Mist gnadenlos aus jeder Zeichenfolge heraus, die versucht, niedliche Spiele mit der Vorstellung zu spielen, dass nur jemand so besessen ist wie Dieser Kaplan-Gefährte wird beleidigend sein (meine Güte, er muss mehr raus!).

Ich werde versuchen, das Dokument auf den neuesten Stand zu bringen.
Regelmäßige Leser, die sich an meine Serien UCS-2 bis UTF-16 erinnern, werden meine Unzufriedenheit mit der simplen Vorstellung von TextBox.MaxLength bemerken und wissen, wie es in diesem Fall mindestens gehandhabt werden sollte Wenn das drakonische Verhalten eine unzulässige Sequenz erzeugt, können andere Teile des .Net Frameworks eine

  • System.Text.EncoderFallbackException: Unicode-Zeichen \ uD850 bei Index 0 kann nicht in die angegebene Codepage übersetzt werden. *

Ausnahme, wenn Sie diese Zeichenfolge an einer anderen Stelle im .Net Framework übergeben (wie es mein Kollege Dan Thompson tat).

Okay, vielleicht ist die vollständige UCS-2- bis UTF-16-Serie für viele unzugänglich.
Aber ist es nicht vernünftig zu erwarten, dass TextBox.Text keinen System.String erzeugt ?das wird nicht dazu führen, dass ein weiteres Stück des .Net Frameworks geworfen wird? Ich meine, es ist nicht so, dass es eine Chance in Form eines Ereignisses auf dem Steuerelement gibt, das Sie über die bevorstehende Kürzung informiert, bei der Sie einfach die intelligentere Validierung hinzufügen können - eine Validierung, die das Steuerelement selbst nicht stört. Ich würde sogar sagen, dass dieses Punk-Steuerelement einen Sicherheitsvertrag bricht, der sogar zu Sicherheitsproblemen führen kann, wenn Sie eine Anwendung mit unerwarteten Ausnahmen als grobe Art von Denial-of-Service beenden können. Warum sollte ein WinForms-Prozess, eine WinForms-Methode, ein WinForms-Algorithmus oder eine WinForms-Technik ungültige Ergebnisse liefern?

Quelle: Michael S. Kaplan MSDN Blog

Matthieu
quelle
Danke, sehr guter Link! Ich habe es der Liste der Probleme in der Frage hinzugefügt.
9

Ich würde nicht unbedingt sagen, dass UTF-16 schädlich ist. Es ist nicht elegant, aber es dient dem Zweck der Abwärtskompatibilität mit UCS-2, genau wie GB18030 mit GB2312 und UTF-8 mit ASCII.

Eine grundlegende Änderung der Unicode-Struktur in Midstream, nachdem Microsoft und Sun riesige APIs für 16-Bit-Zeichen erstellt hatten, war jedoch schädlich. Das Scheitern Bewusstsein für die Änderung zu verbreiten war mehr schädlich.

dan04
quelle
8
UTF-8 ist eine Obermenge von ASCII, aber UTF-16 ist KEINE Obermenge von UCS-2. Obwohl fast eine Obermenge, führt eine korrekte Kodierung von UCS-2 in UTF-8 zu dem als CESU-8 bekannten Greuel; UCS-2 enthält keine Ersatzzeichen, sondern nur normale Codepunkte. Sie müssen daher als solche übersetzt werden. Der eigentliche Vorteil von UTF-16 besteht darin, dass ein Upgrade einer UCS-2-Codebasis einfacher ist als ein vollständiges Umschreiben für UTF-8. Komisch, was?
1
Sicher, technisch UTF-16 ist keine Obermenge von UCS-2, aber wenn war U + D800 bis U + DFFF jemals verwendet für alles außer UTF-16 Surrogate?
Dan04
2
Spielt keine rolle Bei jeder anderen Verarbeitung als dem blinden Durchlaufen des Bytestreams müssen Sie die Ersatzpaare dekodieren. Dies ist nicht möglich, wenn Sie sie als UCS-2 behandeln.
6

UTF-16 ist der beste Kompromiss zwischen Handhabung und Speicherplatz und wird daher von den meisten wichtigen Plattformen (Win32, Java, .NET) zur internen Darstellung von Zeichenfolgen verwendet.

Nemanja Trifunovic
quelle
31
-1, da UTF-8 wahrscheinlich kleiner ist oder sich nicht wesentlich unterscheidet. Für bestimmte asiatische Skripte beträgt UTF-8 drei Bytes pro Glyphe, während UTF-16 nur zwei Bytes enthält. Dies wird jedoch ausgeglichen, indem UTF-8 nur ein Byte für ASCII darstellt (was häufig auch in asiatischen Sprachen in Produktnamen, Befehlen und dergleichen vorkommt Dinge). In den genannten Sprachen vermittelt eine Glyphe mehr Informationen als ein lateinisches Zeichen, so dass es gerechtfertigt ist, mehr Platz zu beanspruchen.
32
Die Kombination der schlimmsten Seiten beider Optionen würde ich nicht als guten Kompromiss bezeichnen.
18
Es ist nicht einfacher als UTF-8. Es ist auch von variabler Länge.
Luiscubal
36
Lassen Sie die Debatten über die Vorteile von UTF-16 beiseite: Was Sie zitiert haben, ist nicht der Grund, warum Windows, Java oder .NET UTF-16 verwenden. Windows und Java stammen aus einer Zeit, in der Unicode eine 16-Bit-Codierung war. UCS-2 war damals eine vernünftige Wahl. Als aus Unicode eine 21-Bit-Codierung wurde, war die Migration auf UTF-16 die beste Wahl, die bestehende Plattformen hatten. Das hatte nichts mit einfacher Handhabung oder Platzmangel zu tun. Es ist nur eine Frage des Erbes.
Joey
10
.NET erbt hier das Windows-Erbe.
Joey
6

Ich habe den Sinn von UTF-16 nie verstanden. Wenn Sie die platzsparendste Darstellung wünschen, verwenden Sie UTF-8. Wenn Sie Text als Text mit fester Länge behandeln möchten, verwenden Sie UTF-32. Wenn Sie beides nicht möchten, verwenden Sie UTF-16. Schlimmer noch, da alle gängigen (mehrsprachigen Basis-) Zeichen in UTF-16 in einen einzelnen Codepunkt passen, sind Fehler, die davon ausgehen, dass UTF-16 eine feste Länge hat, subtil und schwer zu finden, wenn Sie dies versuchen Mit UTF-8 schlägt Ihr Code schnell und laut fehl, sobald Sie versuchen, ihn zu internationalisieren.

dsimcha
quelle
6

Da ich noch keinen Kommentar abgeben kann, poste ich diesen als Antwort, da ich anscheinend die Autoren von nicht kontaktieren kann utf8everywhere.org. Es ist eine Schande, dass ich nicht automatisch das Kommentar-Privileg bekomme, da ich auf anderen Stack-Börsen einen ausreichenden Ruf habe.

Dies ist als Kommentar zur Stellungnahme gedacht : Ja, UTF-16 sollte als schädliche Antwort angesehen werden.

Eine kleine Korrektur:

Um zu verhindern, dass ein UTF-8 versehentlich char*an ANSI-String-Versionen von Windows-API-Funktionen übergeben wird, sollte man UNICODEnicht definieren _UNICODE. _UNICODEKarten funktionieren wie _tcslenzu wcslen, nicht MessageBoxzu MessageBoxW. Stattdessen UNICODEkümmert sich das Define um Letzteres. Zum Beweis ist dies aus dem WinUser.hHeader von MS Visual Studio 2005 :

#ifdef UNICODE
#define MessageBox  MessageBoxW
#else
#define MessageBox  MessageBoxA
#endif // !UNICODE

Dieser Fehler sollte mindestens am korrigiert werden utf8everywhere.org.

Ein Vorschlag:

Vielleicht sollte der Leitfaden ein Beispiel für die explizite Verwendung der Wide-String-Version einer Datenstruktur enthalten, damit es weniger leicht ist, sie zu übersehen oder zu vergessen. Die Verwendung von Wide-String-Versionen von Datenstrukturen anstelle von Wide-String-Versionen von Funktionen macht es noch unwahrscheinlicher, dass versehentlich eine ANSI-String-Version einer solchen Funktion aufgerufen wird.

Beispiel des Beispiels:

WIN32_FIND_DATAW data; // Note the W at the end.
HANDLE hSearch = FindFirstFileW(widen("*.txt").c_str(), &data);
if (hSearch != INVALID_HANDLE_VALUE)
{
    FindClose(hSearch);
    MessageBoxW(nullptr, data.cFileName, nullptr, MB_OK);
}
Jelle Geerts
quelle
Einverstanden; Vielen Dank! Wir werden das Dokument aktualisieren. Das Dokument muss noch weiterentwickelt und Informationen zu Datenbanken hinzugefügt werden. Wir freuen uns über Beiträge von Formulierungen.
Pavel Radzivilovsky
@PavelRadzivilovsky _UNICODEist immer noch da :(
cubuspl42
Danke für das Erinnern. cubus, Jelle, Möchten Sie einen Benutzer zu unserem SVN?
Pavel Radzivilovsky
@Pavel Klar, würde mich freuen!
Jelle Geerts
@ JelleGeerts: Ich entschuldige mich für diese Verzögerung. Sie können uns jederzeit über unsere E-Mails (aus dem Manifest verlinkt) oder Facebook kontaktieren. Wir sind leicht zu finden. Obwohl ich glaube, wir haben das Problem behoben, das Sie hierher gebracht haben (und ich habe es Ihnen gutgeschrieben), sind die gesamten UTF-8-gegen-UTF-16-Debatten immer noch relevant. Wenn Sie mehr beitragen möchten, können Sie uns über diese privaten Kanäle kontaktieren.
Ybungalobill
5

Jemand sagte, UCS4 und UTF-32 seien gleich. Nein, aber ich weiß was du meinst. Eine davon ist jedoch eine Kodierung der anderen. Ich wünschte, sie hätten von Anfang an daran gedacht, Endianess zu spezifizieren, damit hier nicht auch die Endianess-Schlacht ausgetragen würde. Hätten sie das nicht kommen sehen können? Mindestens UTF-8 ist überall gleich (es sei denn, jemand folgt der ursprünglichen Spezifikation mit 6 Bytes).

Wenn Sie UTF-16 verwenden, müssen Sie die Behandlung von Multibyte-Zeichen einbeziehen. Sie können nicht zum n-ten Zeichen wechseln, indem Sie 2N in ein Byte-Array indizieren. Sie müssen es gehen oder Zeichenindizes haben. Ansonsten hast du einen Bug geschrieben.

Die aktuelle Entwurfsspezifikation von C ++ besagt, dass UTF-32 und UTF-16 Little-Endian-, Big-Endian- und nicht spezifizierte Varianten haben können. "Ja wirklich?" Wenn Unicode festgelegt hätte, dass jeder von Anfang an Little-Endian ausführen muss, wäre alles einfacher gewesen. (Ich hätte Big-Endian auch gut verstanden.) Stattdessen haben es einige Leute auf die eine und andere Weise umgesetzt, und jetzt stecken wir mit Dummheit umsonst fest. Manchmal ist es peinlich, Softwareentwickler zu sein.

user22815
quelle
Nicht spezifizierte Endianess soll BOM als erstes Zeichen enthalten, um zu bestimmen, auf welche Weise die Zeichenfolge gelesen werden soll. UCS-4 und UTF-32 sind heutzutage tatsächlich gleich, dh ein numerischer UCS-Wert zwischen 0 und 0x10FFFF, der in einer 32-Bit-Ganzzahl gespeichert ist.
5
@Tronic: Technisch stimmt das nicht. Obwohl UCS-4 jede 32-Bit-Ganzzahl speichern kann, ist es UTF-32 untersagt, die für den Austausch unzulässigen Nichtzeichencodepunkte wie 0xFFFF, 0xFFFE und alle Ersatzzeichen zu speichern. UTF ist eine Transportkodierung, keine interne.
Donnerstag,
Endianness-Probleme sind unvermeidlich, solange verschiedene Prozessoren weiterhin unterschiedliche Byte-Reihenfolgen verwenden. Es wäre jedoch vielleicht nett gewesen, wenn es eine "bevorzugte" Bytereihenfolge für die Dateispeicherung von UTF-16 gegeben hätte.
Qwertie
Obwohl UTF-32 für Codepunkte eine feste Breite hat, hat es für Zeichen keine feste Breite . (Von so etwas wie "Zeichen kombinieren" gehört?) Sie können also nicht einfach zum n-ten Zeichen wechseln , indem Sie 4N in das Bytearray indizieren.
Musiphil
2

Ich denke nicht, dass es schädlich ist, wenn der Entwickler vorsichtig genug ist.
Und sie sollten diesen Kompromiss akzeptieren, wenn sie es auch gut wissen.

Als japanischer Softwareentwickler finde ich UCS-2 groß genug und die Begrenzung des Speicherplatzes vereinfacht anscheinend die Logik und reduziert den Laufzeitspeicher. Daher ist die Verwendung von utf-16 unter UCS-2-Begrenzung gut genug.

Es gibt Dateisysteme oder andere Anwendungen, die Codepunkte und Bytes als proportional voraussetzen, so dass garantiert werden kann, dass die rohe Codepunktnummer in einen Speicher mit fester Größe passt.

Ein Beispiel ist NTFS und VFAT, die UCS-2 als Dateinamen-Speicherkodierung angeben.

Wenn dieses Beispiel wirklich die Unterstützung von UCS-4 erweitern möchte, könnte ich trotzdem zustimmen, dass utf-8 für alles verwendet wird, aber die feste Länge hat gute Punkte wie:

  1. kann die Größe durch Länge garantieren (Datengröße und Codepunktlänge ist proportional)
  2. kann die Codierungsnummer für die Hash-Suche verwenden
  3. Nicht komprimierte Daten haben eine angemessene Größe (im Vergleich zu utf-32 / UCS-4)

In der Zukunft, wenn Speicher- / Verarbeitungsleistung auch in eingebetteten Geräten billig ist, kann es sein, dass das Gerät etwas langsam ist, was zu zusätzlichen Cache-Fehlern oder Seitenfehlern und zusätzlicher Speichernutzung führt. Dies wird jedoch in naher Zukunft wahrscheinlich nicht der Fall sein.

2 Umdrehungen
quelle
3
Für diejenigen, die diesen Kommentar lesen, ist es erwähnenswert, dass UCS-2 nicht dasselbe ist wie UTF-16. Bitte schauen Sie nach, um die Unterschiede zu verstehen.
Mikebabcock
1

"Sollte eine der beliebtesten Kodierungen, UTF-16, als schädlich eingestuft werden?"

Möglicherweise, aber die Alternativen sollten nicht unbedingt als viel besser angesehen werden.

Das grundlegende Problem ist, dass es viele verschiedene Konzepte gibt: Glyphen, Zeichen, Codepunkte und Bytefolgen. Die Zuordnung zwischen diesen ist auch mit Hilfe einer Normalisierungsbibliothek nicht trivial. (Zum Beispiel werden einige Zeichen in europäischen Sprachen, die mit einem lateinischen Skript geschrieben wurden, nicht mit einem einzigen Unicode-Codepunkt geschrieben. Das ist am einfacheren Ende der Komplexität!) Das bedeutet, dass es erstaunlich ist, alles richtig zu machen schwierig; bizarre Bugs sind zu erwarten (und anstatt hier nur darüber zu jammern, teilen Sie dies den Betreuern der betreffenden Software mit).

Die einzige Möglichkeit, UTF-16 als schädlich zu betrachten, im Gegensatz zu beispielsweise UTF-8, besteht darin, dass Codepunkte außerhalb des BMP auf andere Weise codiert werden (als Ersatzpaar). Wenn Code nach Codepunkten zugreifen oder iterieren möchte, muss er sich des Unterschieds bewusst sein. OTOH, es bedeutet, dass ein beträchtlicher Teil des vorhandenen Codes, der "Zeichen" voraussetzt, immer in eine Zwei-Byte-Menge eingepasst werden kann - eine ziemlich häufige, wenn auch falsche Annahme -, kann zumindest weiter funktionieren, ohne alles neu aufzubauen. Mit anderen Worten, zumindest sieht man die Zeichen, die nicht richtig behandelt werden!

Ich würde Ihre Frage auf den Kopf stellen und sagen, dass der ganze Scheiß von Unicode als schädlich angesehen werden sollte und jeder eine 8-Bit-Codierung verwenden sollte, außer ich habe (in den letzten 20 Jahren) gesehen, wohin das führt: schrecklich Verwirrung über die verschiedenen ISO 8859-Kodierungen, plus die ganze Reihe von Kodierungen für Kyrillisch und die EBCDIC-Suite, und… nun, Unicode für all seine Fehler schlägt das. Wenn es nur kein so übler Kompromiss zwischen den Missverständnissen verschiedener Länder wäre.

Donal Fellows
quelle
Wenn wir unser Glück wissen, werden wir in ein paar Jahren in UTF-16 keinen Platz mehr haben. Meh.
Donal Fellows
3
Das grundlegende Problem ist, dass der Text täuschend schwer ist. Kein Ansatz zur digitalen Darstellung dieser Informationen kann unkompliziert sein. Aus dem gleichen Grund sind Daten schwierig, Kalender schwierig, Zeit schwierig, Personennamen schwierig, Postanschriften schwierig: Wenn sich digitale Maschinen mit menschlichen Kulturkonstrukten kreuzen, bricht Komplexität aus. Das ist eine Tatsache des Lebens. Menschen funktionieren nicht mit digitaler Logik.
Aristoteles Pagaltzis