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:
- 𝄞 ( U + 1D11E ) MUSIKSYMBOL G CLEF
- 𝕥 ( U + 1D565 ) MATHEMATISCHES DOPPELSTREIFEN KLEINES T
- 𝟶 ( U + 1D7F6 ) MATHEMATISCHE MONOSPACE-DIGIT-NULL
- 𠂊 ( U + 2008A ) Han-Charakter
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?
Antworten:
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::string
in 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_t
zu C ++ für einen Fehler, ebenso wie die Unicode-Ergänzungen zu C ++ 0x. Was jedoch von STL-Implementierungen verlangt werden muss, ist, dass jederstd::string
oderchar*
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:
wchar_t
oderstd::wstring
in einem anderen als benachbarten Punkt zu APIs akzeptieren UTF-16._T("")
oderL""
UTF-16-Literale (Diese sollten im Rahmen der UTF-16-Abschreibung aus dem Standard entfernt werden)._UNICODE
Konstante empfindlich sind , wie z. B.LPTSTR
oderCreateWindow()
._UNICODE
immer definiert, zu vermeiden vorbeichar*
Strings WinAPI leise zusammengestellt bekommenstd::strings
undchar*
irgendwo im Programm gelten als UTF-8 (wenn nicht anders angegeben)std::string
, obwohl Sie Zeichen * oder Zeichenfolgenliteral übergeben könnenconvert(const std::string &)
.Verwenden Sie nur Win32-Funktionen, die widechars (
LPWSTR
) akzeptieren . Niemals diejenigen, die akzeptierenLPTSTR
oderLPSTR
. Übergeben Sie die Parameter folgendermaßen:(Die Richtlinie verwendet die folgenden Konvertierungsfunktionen.)
Mit MFC-Zeichenfolgen:
Arbeiten mit Dateien, Dateinamen und Fstream unter Windows:
std::string
oderconst char*
Dateinamen an diefstream
Familie. MSVC STL unterstützt keine UTF-8-Argumente, hat jedoch eine nicht standardmäßige Erweiterung, die wie folgt verwendet werden sollte:std::string
Argumente konvertieren nachstd::wstring
mitUtils::Convert
:Wir müssen die Konvertierung manuell entfernen, wenn sich die Einstellung von MSVC zu
fstream
Änderungen ändert.fstream
Weitere Informationen finden Sie im Unicode-Recherche- / Diskussionsfall 4215.fopen()
aus RAII / OOD-Gründen. Verwenden Sie bei Bedarf die_wfopen()
obigen WinAPI-Konventionen.quelle
Unicode-Codepunkte sind keine Zeichen! Manchmal sind es nicht einmal Glyphen (visuelle Formen).
Einige Beispiele:
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.
quelle
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.
quelle
equalsIgnoreCase
Methode 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..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.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:
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).quelle
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.
quelle
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.
quelle
CodePoint
Typ geben sollte , der einen einzelnen Codepunkt (21 Bit) enthält, einenCodeUnit
Typ, der eine einzelne Codeeinheit (16 Bit für UTF-16) enthält, und einenCharacter
Typ, der idealerweise ein vollständiges Graphem unterstützen müsste. Aber das macht es funktional äquivalent zu einemString
...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.
quelle
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.
quelle
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.
quelle
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.
quelle
UTF-16? definitiv schädlich. Nur mein Salzkorn hier, aber es gibt genau drei akzeptable Kodierungen für Text in einem Programm:
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.
quelle
U+10ffff
max 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+ffffffff
bevor 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).U+10FFFF
. Das ist wirklich ein jene Situationen , wenn 21 Bits sind genug für jeden.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 .
quelle
Fügen Sie dies der Liste hinzu:
Quelle: Michael S. Kaplan MSDN Blog
quelle
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.
quelle
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.
quelle
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.
quelle
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 manUNICODE
nicht definieren_UNICODE
._UNICODE
Karten funktionieren wie_tcslen
zuwcslen
, nichtMessageBox
zuMessageBoxW
. StattdessenUNICODE
kümmert sich das Define um Letzteres. Zum Beweis ist dies aus demWinUser.h
Header von MS Visual Studio 2005 :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:
quelle
_UNICODE
ist immer noch da :(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.
quelle
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:
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.
quelle
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.
quelle