Sollte UTF-16 als schädlich angesehen werden?

Kommentare

  • Nicht wirklich korrekt. Ich erkläre, wenn Sie " שָׁ " das zusammengesetzte Zeichen schreiben, das aus " ש besteht ", " div " und " ׁ ", vovels, dann ist das Entfernen jedes einzelnen von ihnen logisch. Sie entfernen einen Codepunkt, wenn Sie die " Rücktaste drücken " und entfernen Sie alle Zeichen einschließlich der Vokale, wenn Sie " del " drücken. Sie erzeugen jedoch niemals einen illegalen Textstatus – illegale Codepunkte. Daher ist die Situation, in der Sie die Rücktaste drücken und unzulässigen Text abrufen, falsch.
  • CiscoIPPhone: Wenn ein Fehler " mehrmals von vielen verschiedenen Personen " und ein paar Jahre später schreibt ein Entwickler in einem Entwickler-Blog, dass " Ob Sie es glauben oder nicht, das Verhalten ist größtenteils beabsichtigt! ", dann (gelinde gesagt) denke ich, dass es ' wahrscheinlich nicht die beste Designentscheidung ist, die jemals getroffen wurde. 🙂 Nur weil es ' absichtlich ist, bedeutet ' nicht, dass es ' nicht ist ein Fehler.
  • Großartiger Beitrag. UTF-16 ist in der Tat das " schlechteste beider Welten ": UTF8 ist variabel, deckt den gesamten Unicode ab und erfordert einen Transformationsalgorithmus zu und von rohen Codepunkten, beschränkt sich auf ASCII, und es gibt keine Endianness-Probleme. UTF32 hat eine feste Länge, erfordert keine Transformation, nimmt jedoch mehr Platz ein und weist Endianness-Probleme auf. So weit so gut, können Sie UTF32 intern und UTF8 für die Serialisierung verwenden. UTF16 hat jedoch keine Vorteile: Es ist ' endianabhängig, ' hat eine variable Länge, es nimmt viel Platz ein, es ' ist nicht ASCII-kompatibel. Der Aufwand für den ordnungsgemäßen Umgang mit UTF16 könnte besser für UTF8 aufgewendet werden.
  • @Ian: UTF-8 hat NICHT die gleichen Einschränkungen wie UTF-8. In UTF-8 können keine Ersatzzeichen vorhanden sein. UTF-8 tarnt 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 und immer wieder und immer wieder gesehen.
  • Außerdem funktioniert UTF-8 nicht ' t habe das Problem, weil jeder es als Codierung mit variabler Breite behandelt. Der Grund, warum UTF-16 das Problem hat, ist, dass jeder es wie eine Codierung mit fester Breite behandelt.

Antwort

Dies ist eine alte Antwort.
Siehe UTF-8 Everywhere für die neuesten Updates.

Meinung: Ja, UTF-16 sollte als schädlich angesehen werden . Der Grund dafür ist, dass es vor einiger Zeit eine falsche Überzeugung gab, dass Widechar das sein wird, was UCS-4 jetzt ist.

Trotz des „Anglozentrismus“ von UTF-8 ist dies der Fall sollte als die einzig nützliche Kodierung für Text angesehen werden. Man kann argumentieren, dass Quellcodes von Programmen, Webseiten und XML-Dateien, Betriebssystemdateinamen und anderen Computer-zu-Computer-Textschnittstellen niemals existieren sollten. Wenn dies jedoch der Fall ist, ist Text nicht nur für menschliche Leser gedacht.

Andererseits ist der UTF-8-Overhead ein geringer Preis, der zu zahlen ist, obwohl er erhebliche Vorteile bietet. Vorteile wie die Kompatibilität mit nicht bekanntem Code, der nur Zeichenfolgen mit char* übergibt. Das ist eine großartige Sache. Es gibt nur wenige nützliche Zeichen, die in UTF-16 KURZER sind als in UTF-8.

Ich glaube, dass alle anderen Codierungen irgendwann sterben werden. Dies betrifft MS-Windows, Java, ICU, Python Verwenden Sie es nach langen Recherchen und Diskussionen nicht mehr. Die Entwicklungskonventionen in my company verbieten die Verwendung von UTF-16 überall außer bei OS-API-Aufrufen, und dies trotz der Wichtigkeit Die Konvertierungsfunktionen wurden entwickelt, um immer angenommene UTF8 std::string s in native UTF-16 zu konvertieren, die Windows selbst unterstützt nicht richtig .

Für Leute, die sagen „ verwenden, was benötigt wird, wo es benötigt wird „, sage ich: Es ist ein großer Vorteil, überall dieselbe Codierung zu verwenden, und ich sehe keinen ausreichenden Grund dafür Andernfalls denke ich, dass das Hinzufügen von wchar_t zu C ++ ein Fehler war, ebenso wie die Unicode-Ergänzungen zu C ++ 0x. Was jedoch von STL-Implementierungen verlangt werden muss, ist, dass alle Der Parameter std::string oder char* wird als Unicode-kompatibel angesehen.

Ich bin auch gegen die Verwendung von „“ Was Sie wollen „Ansatz. Ich sehe keinen Grund für eine solche Freiheit. Es gibt genug Verwirrung über das Thema Text, was zu all dieser kaputten Software führt. Trotzdem bin ich überzeugt, dass Programmierer endlich einen Konsens über UTF-8 als einen richtigen Weg erzielen müssen. (Ich komme aus einem nicht ASCII-sprechenden Land und bin mit Windows aufgewachsen. Daher wird erwartet, dass ich UTF-16 zuletzt aus religiösen Gründen angreife.)

Ich möchte weitere Informationen weitergeben Informationen darüber, wie ich Text unter Windows erstelle und was ich allen anderen zur Kompilierungszeit empfehle, überprüften die Unicode-Korrektheit, die Benutzerfreundlichkeit und die bessere Multi-Plattform-Funktionalität des Codes. Der Vorschlag unterscheidet sich erheblich von dem, was normalerweise als ordnungsgemäße Verwendung von Unicode unter Windows empfohlen wird. Eine eingehende Untersuchung dieser Empfehlungen ergab jedoch die gleiche Schlussfolgerung. Also los gehts:

  • Verwenden Sie wchar_t oder std::wstring nicht an einem anderen Ort als dem angrenzenden Punkt von APIs, die UTF-16 akzeptieren.
  • Verwenden Sie keine _T("") oder L"" UTF-16-Literale (Diese sollten IMO aus dem Standard entfernt werden ,
  • Verwenden Sie keine Typen, Funktionen oder deren Ableitungen, die für die Konstante _UNICODE empfindlich sind, wie z. B. LPTSTR oder CreateWindow().
  • Dennoch ist _UNICODE immer definiert, um Vermeiden Sie es, char* Zeichenfolgen an WinAPI zu übergeben, die stillschweigend kompiliert werden.
  • std::strings und char* irgendwo im Programm gelten als UTF-8 (sofern nicht anders angegeben)
  • Alle meine Zeichenfolgen sind std::string, obwohl Sie char * oder Zeichenfolgenliteral an übergeben können convert(const std::string &).
  • verwendet nur Win32-Funktionen, die Widechars akzeptieren (LPWSTR). Niemals diejenigen, die LPTSTR oder LPSTR akzeptieren. Ü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:

    • Niemals übergeben std::string oder const char* Dateinamenargumente für die Familie fstream. MSVC STL unterstützt keine UTF-8-Argumente, verfügt jedoch über eine nicht standardmäßige Erweiterung, die wie folgt verwendet werden sollte:
    • Konvertieren Sie std::string -Argumente in std::wstring mit Utils::Convert:

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

      Wir müssen manuell Entfernen Sie die Konvertierung, wenn sich die Einstellung von MSVC zu fstream ändert.

    • Dieser Code ist nicht plattformübergreifend und muss möglicherweise manuell geändert werden Die Zukunft
    • Weitere Informationen finden Sie unter fstream Unicode-Forschungs- / Diskussionsfall 4215.
    • Erstellen Sie niemals Textausgabedateien mit Nicht-UTF8-Inhalt
    • Vermeiden Sie aus RAII / OOD-Gründen die Verwendung von fopen(). Verwenden Sie bei Bedarf die oben genannten Konventionen _wfopen() und WinAPI.

// 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 } 

Kommentare

  • Ich kann ' nicht zustimmen. Die Vorteile von utf16 gegenüber utf8 für viele asiatische Sprachen dominieren die Punkte, die Sie ansprechen. Es ist naiv zu hoffen, dass die Japaner, Thailänder, Chinesen usw. diese Kodierung aufgeben werden. Die problematischen Konflikte zwischen Zeichensätzen treten auf, wenn die Zeichensätze bis auf Unterschiede meist ähnlich erscheinen. Ich schlage vor, zu standardisieren auf: fest 7bit: iso-irv-170; 8-Bit-Variable: utf8; 16-Bit-Variable: utf16; 32bit behoben: ucs4.
  • @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-Zeichen 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 Platz so wichtig ist, aber selbst dann ist er für LZ nicht geeignet, und nach LZ oder einer anderen generischen Komprimierung benötigen beide ungefähr die gleiche Größe und Entropie.
  • Grundsätzlich sage ich, dass eine Vereinfachung durch One-Codierung, die 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? Sie müssen sich nicht darum kümmern, welche Art von Unicode Sie verwenden usw. usw. Ich schlage vor, wir Entwickler beschränken UTF-16 auf ganz besondere Fälle schwerwiegender Optimierung, bei denen ein kleines Stück Leistung Mannmonate Arbeit wert ist.
  • 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 fast aller Funktionen hinzu, die Text verarbeiten, und ließen die Multibyte-Versionen einfach in UCS-2 und konvertieren ruf die anderen an. Sie ersetzen später UCS-2 durch UTF-16. Linux hingegen behielt 8-Bit-Codierungen bei und verwendete daher UTF-8, da ' in diesem Fall die richtige Wahl ist.
  • @Pavel Radzivilovsky : Übrigens, Ihre Schriften über " Ich glaube, dass alle anderen Kodierungen irgendwann sterben werden. Dies bedeutet, dass MS-Windows, Java, ICU und Python es nicht mehr als 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 einem Linux programmiert und mit den UTF-8-Zeichen zufrieden ist. Um es ganz klar auszudrücken: Es wird ' nicht passieren .

Antwort

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

Einige Beispiele:

  • Codepunkte mit römischen Zahlen wie „ⅲ“. (Ein einzelnes Zeichen, das wie „iii“ aussieht.)
  • Akzentzeichen wie „á“, die entweder als einzelnes kombiniertes Zeichen „\ u00e1“ oder als Zeichen und getrenntes diakritisches „\ u0061 \“ dargestellt werden können u0301 „.
  • Zeichen wie das griechische Kleinbuchstaben-Sigma, die unterschiedliche Formen für die Mitte (“ σ „) und das Ende (“ ς „) der Wortpositionen haben, aber als Synonyme für die Suche betrachtet werden sollten.
  • 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 erhalten Das Recht ist, eine von einem Experten geschriebene Bibliothek zu verwenden oder Experte zu werden und selbst eine zu schreiben. Wenn Sie nur Codepunkte zählen, leben Sie in einem Zustand der Sünde.

Kommentare

  • Dies. Sehr viel das. UTF-16 kann Probleme verursachen, aber selbst die Verwendung von UTF-32 kann (und wird) immer noch Probleme verursachen.
  • Was ist ein Charakter? Sie können einen Codepunkt als Zeichen definieren und so ziemlich gut auskommen. Wenn Sie eine vom Benutzer sichtbare Glyphe meinen, ist das etwas anderes.
  • @tchrist sicher, dass für die Zuweisung von Speicherplatz diese Definition in Ordnung ist, aber für irgendetwas anderes? Nicht so viel. Wenn Sie ein kombiniertes Zeichen als einziges Zeichen behandeln (dh für eine Lösch- oder " erste N Zeichen " -Operation), haben Sie ' wird seltsames und falsches Verhalten bekommen. Wenn ein Codepunkt nur in Kombination mit mindestens einem anderen eine Bedeutung hat, können Sie ihn ' nicht auf sinnvolle Weise alleine behandeln.
  • @Pacerier, das ist zu spät zur Party, aber ich muss das kommentieren. Einige Sprachen haben sehr große Mengen möglicher Kombinationen von Diakritika (vgl. Vietnamesisch, d. H. Mệt đừ). Es ist sehr hilfreich, Kombinationen anstelle eines Zeichens pro diakritischem Zeichen zu haben.
  • Ein kleiner Hinweis zur Terminologie: Codepunkte entsprechen Unicode-Zeichen ; Worüber Daniel hier spricht, sind vom Benutzer wahrgenommene Zeichen , die Unicode-Graphemclustern entsprechen

Antwort

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

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“, Ich würde sagen: definitiv nicht.

Menschen, die Angst vor Ersatz haben (denken, dass sie Unicode in eine Codierung variabler Länge umwandeln), verstehen die anderen (viel größeren) Komplexitäten, die die Zuordnung zwischen Zeichen und Zeichen machen, nicht Ein sehr komplexer Unicode-Codepunkt: Kombinieren von Zeichen, Ligaturen, Variationsselektoren, Steuerzeichen usw.

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

Kommentare

  • Bitte fügen Sie einige Beispiele hinzu, bei denen UTF-32 in der UNIX-Welt üblich ist!
  • Nein, das tun Sie nicht möchte UTF-16 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 als Mrs UTF-16 bekannt war und dessen Mädchenname UCS-2 war, deutlich überlegen.
  • Ich habe gestern gerade einen Fehler in der Java-Kern-String-Klasse gefunden equalsIgnoreCase -Methode (auch andere in der Zeichenfolgenklasse), die niemals dort 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 sie satt. 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 Wow, also eine nicht ersatzbewusste Funktion (weil sie geschrieben wurde, als es keine gab, und leider so dokumentiert ist, dass es wahrscheinlich ist unmöglich anzupassen – es gibt an, dass .toUpperCase (char)) zu einem falschen Verhalten führt? Sie ' wissen, dass eine UTF-32-Funktion mit einer veralteten Codepunktzuordnung ' nicht besser damit umgehen würde? Auch die gesamte Java-API behandelt Surrogate nicht besonders gut und die komplizierteren Punkte über Unicode überhaupt nicht – und mit der späteren würde die verwendete Codierung ' überhaupt keine Rolle spielen.
  • -1: Ein bedingungsloses .Substring(1) in .NET ist ein triviales Beispiel für etwas, das die Unterstützung für alle Nicht-BMP-Unicodes unterbricht. Alles , das UTF-16 verwendet, hat dieses Problem. ' ist zu einfach, um es als Codierung mit fester Breite zu behandeln, und Sie sehen Probleme zu selten. Dies macht es zu einer aktiv schädlichen Codierung, wenn Sie Unicode unterstützen möchten.

Antwort

Ja, absolut.

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

Wenn Sie sich diese Codepoint-Nutzungsstatistik für einen großen Korpus ansehen von Tom Christiansen Sie werden sehen, dass Trans-8-Bit-BMP-Codepunkte in mehreren Größenordnungen verwendet werden, wenn die Größe größer ist als bei Nicht-BMP-Codepunkten:

 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-Diktum: „Nicht getesteter Code ist fehlerhafter Code“ und umformulieren Sie ihn als „nicht ausgeübter Code ist fehlerhafter Code“. Überlegen Sie, wie oft Programmierer mit Nicht-BMP-Codepunkten umgehen müssen.

Fehler, die damit zusammenhängen, dass UTF-16 nicht als Codierung mit variabler Breite behandelt wird, bleiben viel häufiger unbemerkt als die entsprechenden Fehler in UTF-8 . Einige Programmiersprachen sind noch vorhanden Sie können nicht garantieren, dass Sie UTF-16 anstelle von UCS-2 erhalten, und einige sogenannte Programmiersprachen auf hoher Ebene bieten Zugriff auf Codeeinheiten anstelle von Codepunkten (selbst C soll Ihnen Zugriff auf Codepunkte gewähren, wenn Sie diese verwenden wchar_t, unabhängig davon, was für ein Plat Formulare können).

Kommentare

  • " Fehler im Zusammenhang mit der Nichtbehandlung von UTF-16 als Eine Codierung mit variabler Breite bleibt viel eher unbemerkt als die entsprechenden Fehler in UTF-8. " Dies ist der Kern des Problems und daher die richtige Antwort.
  • Genau. Wenn Ihre UTF-8-Behandlung fehlerhaft ist, ist ' sofort ersichtlich. Wenn Ihre UTF-8-Behandlung fehlerhaft ist, werden Sie ' nur bemerken, wenn Sie ungewöhnliche Han-Zeichen oder mathematische Symbole eingeben.
  • Sehr wahr, aber auf der anderen Seite Was sind Unit-Tests, wenn Sie sich auf das Glück verlassen sollten, Fehler in weniger häufigen Fällen zu finden?
  • @musiphil: Wann haben Sie das letzte Mal einen Unit-Test für Nicht-BMP-Zeichen erstellt?
  • 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. Gleiches gilt für UTF-16: Sie müssen testen, ob Ihr Code sowohl mit Nicht-Ersatzzeichen als auch mit Ersatzzeichen funktioniert. (Jemand könnte sogar argumentieren, dass UTF-8 mindestens vier Hauptfälle hat, während UTF-16 nur zwei hat.)

Antwort

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

Da ich für die Darstellung meiner Meinung zu einer subjektiven Frage abgelehnt wurde, möchte ich näher darauf eingehen. Was genau stört Sie an UTF-16? Würden Sie es vorziehen, wenn alles in UTF-8 codiert 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 wirklich, wenn Sie der Meinung sind, dass UTF-16 als schädlich angesehen werden sollte, weil es verwirrend ist oder nicht ordnungsgemäß implementiert werden kann (Unicode kann es sicherlich sein), welche Methode der Zeichenkodierung wird dann als nicht schädlich angesehen?

BEARBEITEN: Zur Verdeutlichung: Warum sollten unsachgemäße Implementierungen eines Standards als Spiegelbild der Qualität des Standards selbst angesehen werden? Wie andere später festgestellt haben, bedeutet dies nicht, dass das Tool das Tool nicht verwendet, nur weil eine Anwendung ein Tool unangemessen verwendet selbst ist defekt. Wenn dies der Fall wäre, könnten wir wahrscheinlich Dinge wie „var-Schlüsselwort als schädlich“ oder „Threading als schädlich“ sagen. Ich denke, die Frage verwechselt die Qualität und Art des Standards mit den Schwierigkeiten, die viele Programmierer bei der Implementierung haben und es richtig zu verwenden, was meiner Meinung nach eher darauf zurückzuführen ist, dass sie nicht verstehen, wie Unicode funktioniert, als auf Unicode selbst.

Kommentare

  • -1: Wie wäre es, wenn Sie einige der Objekte von Artyom ' ansprechen ons, anstatt ihn nur zu bevormunden?
  • Übrigens: Als ich anfing, diesen Artikel zu schreiben, wollte ich fast schreiben " Sollte Joel über den Softeare-Artikel von Unicode in Betracht gezogen werden schädlich ", weil viele Fehler vorliegen. Zum Beispiel: Die utf-8-Codierung dauert bis zu 4 Zeichen und nicht 6. Außerdem unterscheidet sie nicht zwischen UCS-2 und UTF-16, die wirklich unterschiedlich sind – und tatsächlich die Probleme verursachen, über die ich spreche.
  • Außerdem sollte beachtet werden, dass der UTF-8-Standard, als Joel diesen Artikel schrieb, 6 Bytes und nicht 4 Bytes betrug. RFC 3629 änderte den Standard einige Monate nach dem Schreiben des Artikels auf 4 Bytes. Wie fast alles im Internet lohnt es sich, aus mehr als einer Quelle zu lesen und das Alter Ihrer Quellen zu kennen. Der Link war nicht ' und sollte nicht das " sein, sondern alle ", aber eher ein Ausgangspunkt.
  • Ich würde Bild: utf-8 oder utf-32, das sind: Codierung mit variabler Länge in fast allen Fällen (einschließlich BMP) oder Codierung mit fester Länge immer.
  • @iconiK: Sei nicht albern. UTF-16 ist absolut nicht der de facto Standard für die Textverarbeitung. Zeigen Sie mir eine Programmiersprache, die besser für die Textverarbeitung geeignet ist als Perl, die es immer (na ja, für mehr als) gibt ein Jahrzehnt) verwendete abstrakte Zeichen mit einer zugrunde liegenden UTF-8-Darstellung intern. Aus diesem Grund verarbeitet jedes Perl-Programm automatisch alle Unicodes, ohne dass der Benutzer ständig mit idiotischen Surrogaten herumspielen muss. Die Länge einer Zeichenfolge ist die Anzahl in Codepunkten, nicht in Codeeinheiten. Alles andere ist reine Dummheit, die das Abwärts in die Abwärtskompatibilität versetzt.

Antwort

Es ist nichts falsch mit Utf- 16 Kodierung. Aber Sprachen, die die 16-Bit-Einheiten als Zeichen behandeln, sollten wahrscheinlich als schlecht gestaltet angesehen werden. Es ist ziemlich verwirrend, einen Typ mit dem Namen „char“ zu haben, der nicht immer ein Zeichen darstellt. Da die meisten Entwickler erwarten, dass ein Zeichentyp einen Codepunkt oder ein Zeichen darstellt, wird wahrscheinlich viel Code beschädigt, wenn er Zeichen außerhalb von BMP ausgesetzt wird.

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

Übrigens. Es gibt wahrscheinlich dieselbe Klasse von Fehlern bei Plattformen und Anwendungen, bei denen 8-Bit-Zeichen erwartet werden, denen Utf-8 zugeführt wird.

Kommentare

  • In Java ', wenn Sie sich die Zeitleiste ansehen ( java.com/en/javahistory/timeline.jsp), Sie sehen, dass die primäre Entwicklung von String stattfand, während Unicode 16 Bit betrug (es wurde 1996 geändert). Sie mussten die Fähigkeit verbessern, mit Nicht-BMP-Codepunkten umzugehen, was zu Verwirrung führte.
  • @Kathy: Keine wirkliche Entschuldigung für C #. Im Allgemeinen stimme ich zu, dass es einen CodePoint -Typ geben sollte, der einen einzelnen Codepunkt (21 Bit) und einen CodeUnit -Typ enthält Eine einzelne Codeeinheit (16 Bit für UTF-16) und ein Character -Typ müssten idealerweise ein vollständiges Graphem unterstützen. Aber das macht es funktional äquivalent zu einem String
  • Diese Antwort ist fast zwei Jahre alt, aber ich kann ' t helfen, aber kommentieren. " Es ist hübsch, einen Typ mit dem Namen ' char ' zu haben, der nicht immer ein Zeichen darstellt verwirrend. " Und dennoch verwenden die Leute es die ganze Zeit in C und dergleichen, um ganzzahlige Daten darzustellen, die in einem einzelnen Byte gespeichert werden können.
  • Und ich ' Ich habe eine Menge C-Code gesehen, der ' die Zeichencodierung nicht korrekt verarbeitet.
  • C # hat eine andere Ausrede: Es wurde für Windows entwickelt und Windows wurde auf UCS-2 aufgebaut (' ist sehr ärgerlich, dass Windows-APIs dies auch heute noch nicht können Unterstützung UTF-8). 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, dass dies an Sun ' Klage gegen MS?)

Antwort

Meine persönliche Wahl ist UTF-8 immer verwenden. Es ist der Standard unter Linux für fast alles. Es ist abwärtskompatibel mit vielen Legacy-Apps. Der zusätzliche Speicherplatz für nicht-lateinische Zeichen ist im Vergleich zu den anderen UTF-Formaten sehr gering, und der Platzbedarf für lateinische Zeichen ist erheblich. Im Internet stehen lateinische 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 ist sich bewusst, dass UTF-8 manchmal Mehrbyte-Zeichen enthält. Nicht jeder geht richtig damit um, aber er ist sich normalerweise bewusst, was mehr ist, als für UTF-16 gesagt werden kann. Aber natürlich müssen Sie diejenige auswählen, die für Ihre Anwendung am besten geeignet ist. Deshalb gibt es überhaupt mehr als einen.

Kommentare

  • UTF-16 ist für alles in BMP einfacher, dass ' ist der Grund, warum es so häufig verwendet wird. Aber ich ' bin auch ein Fan von UTF-8, es hat auch keine Probleme mit der Bytereihenfolge, was zu seinem Vorteil funktioniert.
  • Theoretisch ja. In der Praxis gibt es beispielsweise UTF-16BE, was UTF-16 in Big Endian ohne Stückliste bedeutet. Dies ist keine Sache, die ich erfunden habe, dies ist eine tatsächliche Codierung, die in ID3v2.4-Tags zulässig ist (ID3v2-Tags sind scheiße, werden aber leider häufig verwendet). In solchen Fällen müssen Sie die Endianness extern definieren, da der Text selbst ' keine Stückliste enthält. UTF-8 wird immer in eine Richtung geschrieben und hat ' kein solches Problem.
  • 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 Sie es erst bemerken, 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 UCS-2 Braindeath Buggery belassen wurde und daher an 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 bloßer Dummheit und einem Unfall, der darauf wartet, passiert zu werden. Schreiend von UTF-16 aus ausführen.
  • @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 variabler Länge von entweder einer oder zwei 16-Bit-Codeeinheiten pro Codepunkt ". In den häufig gestellten Fragen zu Unicode heißt es: 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 als Unicode betrachtet werden, so einfach ist das.
  • @tchrist Haben Sie eine Quelle für Ihre Statistiken? Wenn gute Programmierer knapp sind, finde ich das gut, weil wir wertvoller werden. 🙂 Bei den Java-APIs werden char-basierte Teile möglicherweise nicht mehr unterstützt. Dies ist jedoch keine Garantie dafür, dass sie ' nicht verwendet werden. Und sie werden definitiv aus Gründen der Kompatibilität nicht entfernt, '.

Antwort

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

Meiner Meinung nach ergeben sich die meisten Probleme aus der Tatsache, dass einige Software heruntergefallen ist hinter dem Unicode-Standard, waren aber nicht schnell, um die Situation zu korrigieren. Opera, Windows, Python, Qt – alle erschienen, bevor UTF-16 allgemein bekannt wurde oder sogar entstand. Ich kann jedoch bestätigen, dass in Opera, Windows Explorer und Notepad keine Probleme mehr mit Zeichen außerhalb von BMP auftreten (zumindest auf meinem PC). Wenn Programme jedoch keine Ersatzpaare erkennen, verwenden sie UTF-16 nicht. Welche Probleme sich auch aus dem Umgang mit solchen Programmen ergeben, 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 werden nur in ganz bestimmten Fällen und Bereichen angetroffen. Laut der offiziellen Unicode-FAQ „sollte die Häufigkeit von Ersatzpaaren selbst in ostasiatischen Texten im Durchschnitt deutlich unter 1% der gesamten Textspeicherung 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 vorgesehen, die solche Zeichen enthalten. Wenn Sie es nicht unterstützen, ist es unangenehm, aber keine Katastrophe.

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 ist, und die gesamte für UCS-2 erstellte Software müsste vollständig neu gestaltet werden, um Unicode-kompatibel zu bleiben. Letzteres würde höchstwahrscheinlich nur die Einführung von Unicode verlangsamen. Außerdem wären wir nicht in der Lage gewesen, die Kompatibilität mit Text in UCS-2 aufrechtzuerhalten, wie dies UTF-8 in Bezug auf ASCII tut.

Nun, abgesehen von allen älteren Problemen, was sind die Argumente gegen die Codierung Ich bezweifle wirklich, dass Entwickler heutzutage nicht wissen, dass UTF-16 eine variable Länge hat. Es ist überall mit Wikipedia geschrieben. UTF-16 ist viel weniger schwer zu analysieren als UTF-8, wenn jemand auf Komplexität als mögliches Problem hingewiesen hat. Es ist auch falsch zu glauben, dass es leicht ist, die Stringlänge nur in UTF-16 zu bestimmen. Wenn Sie UTF-8 oder UTF-32 verwenden, sollten Sie sich dennoch bewusst sein, dass ein Unicode-Codepunkt nicht unbedingt ein Zeichen bedeutet. Abgesehen davon glaube ich nicht, dass die Codierung wesentlich ist.

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, wenn das verwendet, was benötigt wird, wo es benötigt wird In einigen Fällen müssen Sie mit ASCII kompatibel bleiben und UTF-8 benötigen. In einigen Fällen möchten Sie mit Han-Ideogrammen arbeiten und mit UTF-16 Platz sparen. In einigen Fällen benötigen Sie universelle Darstellungen von Zeichen, die ein festes Zeichen verwenden -Längencodierung. Verwenden Sie, was besser geeignet ist, machen Sie es einfach richtig.

Kommentare

  • Das ' ist eine ziemlich blinkende, anglozentrische Ansicht, Malcolm. Fast auf Augenhöhe mit " ASCII ist gut genug für die USA – der Rest der Welt sollte zu uns passen ".
  • Eigentlich bin ich ' aus Russland und stoße die ganze Zeit auf Kyrilliker (einschließlich meiner eigenen Programme), also ziehe ich ' an Ich glaube nicht, dass ich eine anglozentrische Sichtweise habe. 🙂 Das Erwähnen von ASCII ist nicht ganz angemessen, da ' kein Unicode ist und ' bestimmte Zeichen nicht unterstützt. UTF-8, UTF-16, UTF-32 unterstützen dieselben internationalen Zeichensätze. Sie sind nur für die Verwendung in ihren spezifischen Bereichen vorgesehen. Und genau das ist mein Punkt: Wenn Sie hauptsächlich Englisch verwenden, verwenden Sie UTF-8, wenn Sie hauptsächlich Kyrillik verwenden, verwenden Sie UTF-16, wenn Sie alte Sprachen verwenden, verwenden Sie UTF-32. Ganz einfach.
  • " Nicht wahr, asiatische Skripte wie Japanisch, Chinesisch oder Arabisch gehören ebenfalls 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.
  • @Marcolm: " BMP selbst ist tatsächlich sehr groß und sicherlich groß genug, um alle heutzutage verwendeten Skripte aufzunehmen " Nicht wahr. Zu diesem Zeitpunkt hat Unicode bereits ungefähr 100.000 Zeichen zugewiesen, weit mehr als BMP aufnehmen kann. Außerhalb von BMP gibt es große Teile chinesischer Schriftzeichen. Einige von ihnen werden von GB-18030 (obligatorischer chinesischer Standard) benötigt. Andere sind nach (nicht obligatorischen) japanischen und koreanischen Standards erforderlich. Wenn Sie also versuchen, etwas in diesen Märkten zu verkaufen, benötigen Sie mehr als BMP-Unterstützung.
  • Alles, was UTF-16 verwendet, aber nur schmale 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 na ï ve Leute dazu bringt, fehlerhaften Code zu schreiben. Entweder können Sie mit Unicode-Text umgehen oder nicht. Wenn Sie dies nicht können, wählen Sie eine Teilmenge aus, die genauso dumm ist wie die reine ASCII-Textverarbeitung.

Antwort

Die jahrelange Internationalisierungsarbeit von Windows, insbesondere in ostasiatischen Sprachen, hat mich möglicherweise korrumpiert, aber ich neige zu UTF-16 für programminterne Darstellungen von Zeichenfolgen und UTF-8 für die Netzwerk- oder Dateispeicherung von Klartext- wie Dokumente. UTF-16 kann jedoch normalerweise unter Windows schneller verarbeitet werden, sodass dies der Hauptvorteil der Verwendung von UTF-16 unter Windows ist.

Durch den Sprung zu UTF-16 wurde die Angemessenheit der durchschnittlichen Produkthandhabung erheblich verbessert internationaler Text.Es gibt nur wenige enge Fälle, in denen die Ersatzpaare berücksichtigt werden müssen (Löschungen, Einfügungen und Zeilenumbrüche im Grunde), 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 ungefähr genauso schnell in der richtigen Reihenfolge. auch UTF-8 codiert. 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 es sie normalerweise von UTF-8-Seiten in eine interne UTF-16-Darstellung konvertiert; I. „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 platzsparend ist. Es ist also so ziemlich ein Nichtstarter.

Kommentare

  • Ich habe ' nicht ganz verstanden Kommentar zu UTF-8- und Ersatzpaaren. Ersatzpaare sind nur ein Konzept, das für die UTF-16-Codierung von Bedeutung ist, oder? Vielleicht kann Code, der direkt von der UTF-16-Codierung in die UTF-8-Codierung konvertiert wird, dies falsch machen In diesem Fall besteht das Problem darin, das UTF-16 falsch zu lesen und nicht das UTF-8 zu schreiben. Ist das richtig?
  • Was Jason ' spricht, ist Software, die Implementiert UTF-8 absichtlich auf diese Weise: Erstellen Sie ein Ersatzpaar und dann UTF-8 en codieren Sie jede Hälfte separat. Der korrekte Name für diese Codierung lautet CESU-8, aber Oracle (z. B.) stellt ihn falsch als UTF-8 dar. Java verwendet ein ähnliches Schema für die Objektserialisierung, aber es ist ' eindeutig als " Modified UTF-8 und nur für den internen Gebrauch. (Wenn wir jetzt nur die Leute 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 Codierung mit variabler Länge. und nicht gleich UCS4, einem bestimmten Bereich von Codepunkten.
  • @Eonil, UTF-32 kann nur dann von UCS4 unterschieden werden, wenn wir einen Unicode-Standard haben, der so etwas wie UCS5 oder größer enthält.
  • @JasonTrue Trotzdem sind nur die Ergebnisse zufällig gleich und nicht vom Design garantiert. Dasselbe geschah bei der 32-Bit-Speicheradressierung Y2K, UTF16 / UCS2. Oder haben wir eine Garantie für diese Gleichheit? Wenn ja, würde ich das gerne nutzen. Aber ich ' möchte keinen möglichen zerbrechlichen Code schreiben. Ich schreibe einen Code auf Zeichenebene, und das Fehlen einer garantierten Möglichkeit zum Transcodieren zwischen UTF-Codepunkten < – > nervt mich sehr .

Antwort

UTF-8 ist definitiv der richtige Weg, möglicherweise begleitet von UTF-32 für interne Verwendung in Algorithmen, die einen Hochleistungs-Direktzugriff benötigen (bei denen jedoch das Kombinieren von Zeichen ignoriert wird).

Sowohl UTF-16 als auch UTF-32 (sowie ihre LE / BE-Varianten) leiden unter Endianess-Problemen, daher sollten sie dies tun Niemals extern verwenden.

Kommentare

  • Auch mit UTF-8 ist ein zeitlich konstanter Direktzugriff möglich. Verwenden Sie nur Codeeinheiten anstelle von Codepunkten. Vielleicht benötigen Sie einen echten zufälligen Codepunktzugriff, aber ich ' habe noch nie einen Anwendungsfall gesehen, und Sie ' möchten dies genauso wahrscheinlich Stattdessen zufälliger Graphemclusterzugriff.

Antwort

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

  • ASCII: Wenn es um Dinge auf niedriger Ebene geht (z. B. Mikrocontroller), die sich nichts Besseres leisten können
  • UTF8: Speicherung auf Medien mit fester Breite wie Dateien
  • Ganzzahl-Codepunkte („CP“?): Ein Array der größten Ganzzahlen, die für Ihre Programmiersprache geeignet sind und Plattform (zerfällt in ASCII im Grenzbereich niedriger Resorces). Sollte auf älteren Computern int32 und auf 64 Computern mit 64-Bit-Adressierung int64 sein.

  • Offensichtlich Schnittstellen zur Verwendung von Legacy-Code Welche Codierung ist erforderlich, damit der alte Code richtig funktioniert?

Kommentare

  • @simon buchan, der U+10ffff max wird aus dem Fenster gehen, wenn (nicht wenn) ihnen die Codepunkte ausgehen. Das heißt, die Verwendung von int32 auf einem p64-System für die Geschwindigkeit ist wahrscheinlich sicher, da ich bezweifle, dass sie ' überschreitet U+ffffffff, bevor Sie muss um 2050 Ihren Code für 128-Bit-Systeme neu schreiben. (Dies ist der Punkt, an dem " das größte int verwendet, das praktisch ist " im Gegensatz zu " dem größten verfügbaren " (das wäre wahrscheinlich int256 oder bignums oder so).)
  • @David: Unicode 5.2 codiert 107.361 Codepunkte.Es gibt 867.169 nicht verwendete Codepunkte. " wenn " nur albern ist. 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 zu sein, wenn ein 64-Bit-System das gesamte Internet im Adressraum ' halten kann.)
  • @David: Ihre ", wenn " sich auf das Auslaufen von Unicode-Codepunkten bezog, nicht auf einen 128-Bit-Switch, der ja wird in den nächsten Jahrhunderten sein. Im Gegensatz zum Speicher gibt es kein exponentielles Wachstum von Zeichen, daher hat das Unicode-Konsortium speziell garantiert, dass sie niemals einen Codepunkt über U+10FFFF. Dies ist wirklich eine dieser Situationen, in denen 21 Bit für jeden ausreichen.
  • @Simon Buchan: Zumindest bis zum ersten Kontakt. 🙂
  • Unicode wird verwendet, um sicherzustellen, dass auch über U + FFFF keine Codepunkte vorhanden sind.

Antwort

Unicode definiert Codepunkte bis 0x10FFFF (1.114.112 Codes), wobei alle Anwendungen in einer mehrsprachigen Umgebung ausgeführt werden mit Zeichenfolgen / Dateinamen usw. sollte dies korrekt behandeln.

Utf-16 : deckt nur 1.112.064 ab Codes. Obwohl die am Ende von Unicode aus den Flugzeugen 15-16 (Private Use Area) stammen. Es kann in Zukunft nicht weiter wachsen, außer das Konzept Utf-16 zu brechen.

Utf-8 : deckt theoretisch 2.216.757.376 Codes ab. Der aktuelle Bereich von Unicode -Codes kann durch eine maximale 4-Byte-Sequenz dargestellt werden. Es leidet nicht unter dem Problem 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 es wahrscheinlich auch in Zukunft nicht sein.

Diese Fakten sind selbsterklärend. Ich verstehe es nicht, die allgemeine Verwendung von Utf-16 zu befürworten. Es ist variabel längencodiert (kann nicht über den Index aufgerufen werden), es hat Probleme, den gesamten Unicode -Bereich auch derzeit abzudecken. Die Bytereihenfolge muss behandelt werden usw. Ich sehe keinen Vorteil, außer dass sie nativ in Windows und einigen anderen Orten verwendet wird. 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 durchzuführen plattformabhängig (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 befassen, die Tatsache nicht einmal kennen oder ignorieren Es ist in variabler Länge codiert.

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

Kommentare

  • 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 Byte definiert und den Bereich 0xD800-0xDFFF explizit vom gültigen Codepunktbereich ausgeschlossen hat. Dieser Bereich wird für die Erstellung von Ersatz verwendet Paare. Somit kann jeder gültige Unicode-Text mit jeder dieser Codierungen dargestellt werden. Auch um in die Zukunft zu wachsen. ' scheint nicht, dass 1 Million Codepunkte in ferner Zukunft nicht ausreichen würden.
  • @Kerrek: Falsch: UCS-2 ist kein gültiger 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 plus ein paar mehr darstellen. Wiederholen: UCS-2 ist keine gültige Unicode-Codierung, auch nicht mehr als ASCII.
  • " Ich verstehe die allgemeine Verwendung von Utf- nicht. 8 . Es ist variabel längencodiert (kann nicht über den Index aufgerufen werden). "
  • @Ian Boyd. Die Notwendigkeit, auf das einzelne Zeichen einer Zeichenfolge in einem Direktzugriffsmuster zuzugreifen, besteht darin unglaublich übertrieben. 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, vorausgesetzt, Sie befinden sich bei UTF-8-Zeichen N, O (1) ist, gibt es kein Problem. Es ist äußerst wenig erforderlich, auf Zeichenfolgen wahlfrei zuzugreifen. Ob Sie der Meinung sind, dass sich der Speicherplatz für UTF-32 anstelle von UTF-8 lohnt, ist Ihre eigene Meinung, aber für mich ist dies insgesamt kein Problem.
  • @tchrist, das werde ich gewähren Ihre Zeichenfolgen werden praktisch immer nacheinander verarbeitet, wenn Sie die umgekehrte Iteration als " sequentielle " einschließen und den Vergleich des nachfolgenden Endes von etwas weiter ausdehnen eine Zeichenfolge zu einer bekannten Zeichenfolge. Zwei sehr häufige Szenarien sind das Abschneiden von Leerzeichen am Ende von Zeichenfolgen und das Überprüfen der Dateierweiterung am Ende eines Pfads.

Antwort

Fügen Sie dies der Liste hinzu:

Das vorgestellte Szenario ist einfach (noch einfacher, da ich es hier vorstellen werde, als es ursprünglich war! ): 1. Eine WinForms-Textbox befindet sich in einem leeren Formular. Die maximale Länge ist auf 20 festgelegt.

2. Der Benutzer gibt in die TextBox ein oder vielleicht Fügt Text ein.

3. Egal, was Sie eingeben oder in die TextBox einfügen, Sie sind auf 20 beschränkt, obwohl es bei Text jenseits der 20 mitfühlend piept (YMMV hier; ich habe mein Soundschema geändert um mir diesen Effekt zu geben!).

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 gerade selbst in mehreren Programmiersprachen mit WinForms geschrieben, weil ich gelangweilt war und es noch nie zuvor ausprobiert hatte. Und mit Text in mehreren tatsächlichen Sprachen, weil ich so verkabelt bin und mehr Tastaturlayouts habe als möglicherweise irgendjemand im gesamten verdammten Universum.

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

Dies hat nicht funktioniert, was es wert ist.

Stattdessen habe ich Folgendes eingegeben: 20 Zeichen in meine Magic Carpet Ride Form:

0123401234012340123 𠀀

Oh oh.

Das letzte Zeichen ist U + 20000, das erste Erweiterung B Ideogramm von Unicode (auch bekannt als U + d840 U + dc00, an seine engen Freunde, vor denen er sich nicht schämt, sozusagen vor) entkleidet zu werden ….

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.

Was es wirklich bedeutet, ist

Ruft ab oder setzt die maximale Anzahl von UTF-16 LE-Cod Die Einheiten, die manuell in das Textfeld eingegeben werden können und den lebenden Mist gnadenlos aus jeder Zeichenfolge herausschneiden, die versucht, niedliche Spiele mit der Vorstellung eines sprachlichen Charakters zu spielen, dass nur jemand, der so besessen ist wie dieser Kaplan-Gefährte, beleidigend sein wird (meine Güte, er muss Holen Sie mehr heraus!).

Ich werde versuchen, das Dokument zu aktualisieren …
Regelmäßige Leser, die Denken Sie daran, dass meine UCS-2 bis UTF-16 -Serie meine Unzufriedenheit mit dem simplen Begriff TextBox.MaxLength bemerken wird und wie es mindestens in diesem Fall behandelt werden sollte, in dem sein drakonisches Verhalten eine unzulässige Sequenz erzeugt, die andere Teile des .Net Frameworks möglicherweise eine

  • System.Text.EncoderFallbackException auslösen : Unicode-Zeichen \ uD850 am 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 getan hat).

Nun okay, vielleicht ist die vollständige UCS-2 bis UTF-16-Serie für viele unerreichbar.
Aber nicht „Ist es nicht zu erwarten, dass TextBox.Text kein System.String erzeugt, das nicht dazu führt, dass ein weiteres Teil des .Net Frameworks ausgelöst 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 dem Steuerelement selbst nichts ausmacht. Ich würde Gehen Sie so weit zu sagen, dass diese Punk-Kontrolle einen Sicherheitsvertrag bricht, der sogar zu Sicherheitsproblemen führen kann, wenn Sie unerwartete Ausnahmen zum Beenden einer Anwendung als grobe Art von Denial-of-Service klassifizieren können. Warum sollte ein WinForms-Prozess oder eine WinForms-Methode oder Algorithmus oder Technik führen zu ungültigen Ergebnissen?

Quelle: Michael S.Kaplan MSDN Blog

Kommentare

  • Danke, sehr guter Link! Ich ' habe es der Problemliste in der Frage hinzugefügt.

Antwort

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 Struktur von Unicode im Midstream, nachdem Microsoft und Sun riesige APIs mit 16-Bit-Zeichen erstellt hatten, war schädlich. Das Versäumnis, das Bewusstsein für die Änderung zu verbreiten, war schädlicher.

Kommentare

  • UTF-8 ist eine Obermenge von ASCII , aber UTF-16 ist KEINE Obermenge von UCS-2. Obwohl fast eine Obermenge, führt eine korrekte Codierung von UCS-2 in UTF-8 zu dem als CESU-8 bekannten Gräuel; UCS-2 hat ' keine Ersatzzeichen, sondern nur gewöhnliche Codepunkte, daher müssen sie als solche übersetzt werden. Der eigentliche Vorteil von UTF-16 besteht darin, dass es ' einfacher ist, eine UCS-2-Codebasis zu aktualisieren, als UTF-8 vollständig neu zu schreiben. Witzig, oder?
  • Sicher, technisch gesehen ist UTF-16 nicht ' eine Obermenge von UCS-2, aber wann waren U + D800 bis U + DFFF jemals für alles außer UTF-16-Ersatz verwendet?
  • Ist ' nicht wichtig. Für jede andere Verarbeitung als das blinde Durchlaufen des Bytestreams müssen Sie die Ersatzpaare dekodieren, was Sie ' nicht tun können, wenn Sie ' erneut behandeln es als UCS-2.

Antwort

UTF-16 ist die bester Kompromiss zwischen Handling und Speicherplatz und deshalb verwenden die meisten großen Plattformen (Win32, Java, .NET) ihn für die interne Darstellung von Zeichenfolgen.

Kommentare

  • -1, da UTF-8 wahrscheinlich kleiner oder nicht signifikant unterschiedlich ist. Für bestimmte asiatische Skripte beträgt UTF-8 drei Bytes pro Glyphe, während UTF-16 nur zwei ist, dies ist jedoch der Fall Ausgeglichen durch UTF-8, das nur ein Byte für ASCII ist (was häufig sogar in asiatischen Sprachen in Produktnamen, Befehlen und dergleichen vorkommt). In den genannten Sprachen vermittelt ein Glyphe mehr Informationen als ein lateinisches Zeichen, so dass dies gerechtfertigt ist damit es mehr Platz einnimmt.
  • Ich würde nicht das Kombinieren der Arbeit nennen Die beiden Seiten beider Optionen sind ein guter Kompromiss.
  • Es ist ' nicht einfacher als UTF-8. ' hat ebenfalls eine variable Länge.
  • Lassen Sie die Debatten über die Vorteile von UTF-16 beiseite: Was Sie zitiert haben, ist nicht das Grund für Windows, Java oder .NET mit UTF-16. Windows und Java stammen aus einer Zeit, in der Unicode eine 16-Bit-Codierung war. UCS-2 war damals eine vernünftige Wahl. Als Unicode zu einer 21-Bit-Codierung wurde, war die Migration auf UTF-16 die beste Wahl für vorhandene Plattformen. Das hatte nichts mit einfacher Handhabung oder Platzkompromissen zu tun. ' ist nur eine Frage des Vermächtnisses.
  • .NET erbt hier das Windows-Vermächtnis.

Antwort

Ich habe den Punkt von UTF-16 nie verstanden. Wenn Sie die platzsparendste Darstellung wünschen, verwenden Sie UTF-8. Wenn Sie in der Lage sein möchten Behandeln Sie Text als feste Länge, verwenden Sie UTF-32. Wenn Sie keine möchten, verwenden Sie UTF-16. Schlimmer noch, da alle allgemeinen Zeichen (mehrsprachige Grundebene) in UTF-16 in einen einzelnen Codepunkt passen, Fehler, die davon ausgehen Dass UTF-16 eine feste Länge hat, ist subtil und schwer zu finden. Wenn Sie dies mit UTF-8 versuchen, schlägt Ihr Code jedoch schnell und laut fehl, sobald Sie versuchen, sich zu internationalisieren.

Antwort

Da ich noch keinen Kommentar abgeben kann, poste ich dies als Antwort, da ich anscheinend die Autoren von utf8everywhere.org. Es ist schade, dass ich das Kommentarprivileg nicht automatisch erhalte, da ich bei anderen Stapelbörsen genügend Ruf habe.

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

Eine kleine Korrektur:

Um zu verhindern, dass versehentlich ein UTF-8 char* in ANSI-String-Versionen von Windows-API-Funktionen übergeben wird, sollte dies geschehen Definieren Sie UNICODE, nicht _UNICODE. _UNICODE ordnet Funktionen wie _tcslen wcslen zu, nicht MessageBox bis MessageBoxW. Stattdessen kümmert sich die Definition UNICODE um Letzteres. Zum Beweis stammt dies aus dem WinUser.h -Header von MS Visual Studio 2005:

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

Zumindest Dieser Fehler sollte bei utf8everywhere.org behoben werden.

Ein Vorschlag:

Vielleicht sollte der Leitfaden ein Beispiel für die explizite Verwendung des Wide- enthalten. String-Version einer Datenstruktur, damit sie weniger leicht übersehen / vergessen werden kann.Die Verwendung von Wide-String-Versionen von Datenstrukturen zusätzlich zur Verwendung von Wide-String-Versionen von Funktionen macht es noch weniger wahrscheinlich, dass versehentlich eine ANSI-String-Version einer solchen Funktion aufgerufen wird.

Beispiel für das Beispiel:

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); } 

Kommentare

  • 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.
  • @PavelRadzivilovsky _UNICODE ist immer noch da 🙁
  • danke für die Erinnerung. Cubus, Jelle, Möchten Sie einen Benutzer für unsere SVN?
  • @Pavel Sicher, würde es begrüßen!
  • @JelleGeerts: Ich entschuldige mich für diese Verzögerung. Sie können uns jederzeit über unsere E-Mails (verlinkt) kontaktieren aus dem Manifest) oder Facebook. Wir sind leicht zu finden. Obwohl ich glaube, dass wir das Problem behoben haben, das Sie hierher gebracht haben (und ich habe es Ihnen dort gutgeschrieben), sind die gesamten Debatten zwischen UTF-8 und UTF-16 immer noch relevant. Wenn Sie mehr zu tun haben Sie können uns gerne über diese privaten Kanäle kontaktieren.

Antwort

Jemand sagte, UCS4 und UTF-32 seien es Nein, aber ich weiß, was du meinst. Einer von ihnen ist jedoch eine Kodierung des anderen. Ich wünschte, sie hätten von Anfang an daran gedacht, Endianness zu spezifizieren, damit wir nicht auch hier den Endianess-Kampf führen würden. Konnten sie das nicht kommen sehen? Zumindest ist UTF-8 überall gleich re (es sei denn, jemand folgt der ursprünglichen Spezifikation mit 6 Byte).

Wenn Sie UTF-16 verwenden, müssen Sie die Behandlung für Multibyte-Zeichen einschließen. Sie können nicht zum N-ten Zeichen wechseln, indem Sie 2N in ein Byte-Array indizieren. Sie müssen es durchlaufen oder Zeichenindizes haben. Andernfalls haben Sie einen Fehler 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 angegeben hätte, dass jeder von Anfang an Little-Endian machen müsste, wäre alles einfacher gewesen. (Ich hätte auch mit Big-Endian gut zurechtgekommen.) Stattdessen haben einige Leute es auf die eine oder andere Weise implementiert, und jetzt sind wir „umsonst albern. Manchmal ist es peinlich, Software-Ingenieur zu sein.“ / p>

Kommentare

  • Nicht spezifizierte Endianess soll Stückliste als erstes Zeichen enthalten, mit dem bestimmt wird, wie die Zeichenfolge gelesen werden soll. UCS-4 und UTF-32 sind heutzutage tatsächlich gleich, d. H. Ein numerischer UCS-Wert zwischen 0 und 0x10FFFF, der in einer 32-Bit-Ganzzahl gespeichert ist.
  • @Tronic: Technisch gesehen ist dies nicht der Fall. Obwohl UCS-4 jede 32-Bit-Ganzzahl speichern kann, ist es UTF-32 untersagt, die für den Austausch unzulässigen Codepunkte ohne Zeichen wie 0xFFFF, 0xFFFE und alle Ersatzzeichen zu speichern. UTF ist eine Transportcodierung, keine interne.
  • Endianness-Probleme sind unvermeidbar, solange verschiedene Prozessoren weiterhin unterschiedliche Bytereihenfolgen verwenden. Es wäre jedoch vielleicht schön gewesen, wenn es eine " bevorzugte " Bytereihenfolge für die Dateispeicherung von UTF-16 gegeben hätte.
  • Obwohl UTF-32 für Codepunkte eine feste Breite hat, ist es für Zeichen keine feste Breite. (Sie haben von etwas gehört, das " heißt und Zeichen " kombiniert?) Sie können also ' nicht gehen zum N ' th Zeichen einfach durch Indizieren von 4N in das Bytearray.

Antwort

Ich glaube 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-Beschränkung gut genug.

Es gibt ein Dateisystem oder eine andere Anwendung, bei der davon ausgegangen wird, dass Codepunkte und Bytes proportional sind, sodass garantiert werden kann, dass die rohe Codepunktnummer in einen Speicher mit fester Größe passt.

Ein Beispiel ist NTFS und VFAT, wobei UCS-2 als Dateinamen-Speichercodierung angegeben wird.

Wenn dieses Beispiel wirklich erweitert werden soll, um UCS-4 zu unterstützen, könnte ich sowieso zustimmen, utf-8 für alles zu verwenden, aber feste Länge hat gute Punkte wie:

  1. kann garantieren Sie die Größe nach Länge (Datengröße und Codepunktlänge sind 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 Zukunft, wenn Speicher- / Verarbeitungsleistung selbst in eingebetteten Geräten billig ist, akzeptieren wir möglicherweise, dass das Gerät für zusätzliche Cache-Fehler oder Seitenfehler und zusätzlichen Speicher etwas langsam ist Verwendung, aber dies wird in naher Zukunft nicht passieren, denke ich …

Kommentare

  • Für diejenigen, die diesen Kommentar lesen, ist es erwähnenswert, dass UCS- 2 ist nicht dasselbe wie UTF-16. Bitte schauen Sie sich die Unterschiede an, um sie zu verstehen.

Antwort

„Sollte eine der beliebtesten sein Codierungen, UTF-16, werden als schädlich angesehen? „

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 Byte-Sequenzen. Die Zuordnung zwischen diesen ist selbst 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. Und das ist am einfacheren Ende der Komplexität!) Dies bedeutet, dass alles korrekt ist ziemlich erstaunlich schwierig; bizarre Fehler sind zu erwarten (und anstatt hier nur darüber zu jammern, informieren Sie die Betreuer über die betreffende Software).

Die einzige Möglichkeit, wie UTF- 16 kann als schädlich angesehen werden, im Gegensatz zu beispielsweise UTF-8, da es eine andere Art der Codierung von Codepunkten außerhalb des BMP hat (als Ersatzpaar). Wenn Code auf Codepunkte zugreifen oder diese durch Codepunkte iterieren möchte, Das bedeutet, dass es sich des Unterschieds bewusst sein muss. OTOH bedeutet, dass ein wesentlicher Teil des vorhandenen Codes, der „Zeichen“ annimmt, immer in eine Zwei-Byte-Menge eingepasst werden kann – eine ziemlich häufige, wenn auch falsche Annahme – Am wenigsten weiterarbeiten, ohne alles neu aufzubauen. Mit anderen Worten, zumindest können Sie diese Charaktere sehen s, die nicht richtig gehandhabt werden!

Ich würde Ihre Frage auf den Kopf stellen und sagen, dass der ganze verdammte 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: schreckliche Verwirrung über die verschiedenen ISO 8859-Codierungen sowie die gesamte für Cyrillic und die EBCDIC-Suite verwendete Codierung, und… nun, Unicode für all seine Fehler übertrifft dies . Wenn es nur kein so böser Kompromiss zwischen verschiedenen Ländern wäre, Missverständnisse.

Kommentare

  • Da wir unser Glück kennen, haben wir in ein paar Jahren ' In UTF-16 wird uns der Speicherplatz ausgehen. Meh.
  • Das grundlegende Problem ist, dass Text täuschend schwer ist. Kein Ansatz zur digitalen Darstellung dieser Informationen kann unkompliziert sein. ' ist der gleiche Grund, warum Daten schwierig sind, Kalender schwierig sind, Zeit schwierig ist, persönliche Namen schwierig sind, Postanschriften schwierig sind: Immer wenn sich digitale Maschinen mit menschlichen kulturellen Konstrukten überschneiden, Komplexität bricht aus. Es ist eine Tatsache des Lebens. Menschen funktionieren nicht mit digitaler Logik.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Deep Theme Powered by WordPress