Wie viele Zeichen können mit Unicode zugeordnet werden?

82

Ich bitte um die Anzahl aller möglichen gültigen Kombinationen in Unicode mit Erklärung. Ich weiß, dass ein Zeichen als 1,2,3 oder 4 Bytes codiert werden kann. Ich verstehe auch nicht, warum Fortsetzungsbytes Einschränkungen haben, obwohl das Startbyte dieses Zeichens löscht, wie lange es sein sollte.

Ufuk Hacıoğulları
quelle

Antworten:

117

Ich bitte um die Anzahl aller möglichen gültigen Kombinationen in Unicode mit Erklärung.

1.111.998 : 17 Flugzeuge × 65.536 Zeichen pro Flugzeug - 2048 Ersatzzeichen - 66 Nichtzeichen

Beachten Sie, dass UTF-8 und UTF-32 theoretisch viel mehr als 17 Ebenen codieren können, der Bereich jedoch aufgrund der Einschränkungen der UTF-16-Codierung eingeschränkt ist .

In Unicode 12.1 werden tatsächlich 137.929 Codepunkte zugewiesen .

Ich verstehe auch nicht, warum Fortsetzungsbytes Einschränkungen haben, obwohl das Startbyte dieses Zeichens löscht, wie lange es sein sollte.

Der Zweck dieser Einschränkung in UTF-8 besteht darin, die Codierung selbstsynchronisierend zu machen .

Betrachten Sie als Gegenbeispiel die chinesische GB 18030-Codierung . Dort wird der Buchstabe ßals Bytefolge dargestellt 81 30 89 38, die die Kodierung der Ziffern 0und enthält 8. Wenn Sie also eine Zeichenfolgensuchfunktion haben, die nicht für diese codierungsspezifische Eigenart ausgelegt ist, wird bei der Suche nach der Ziffer 8ein falsches Positiv im Buchstaben gefunden ß.

In UTF-8 kann dies nicht passieren, da die Nichtüberlappung zwischen Lead-Bytes und Trail-Bytes garantiert, dass die Codierung eines kürzeren Zeichens niemals innerhalb der Codierung eines längeren Zeichens erfolgen kann.

dan04
quelle
2
Der Artikel "Selbstsynchronisierung", den Sie verlinkt haben, erklärt nicht, was überhaupt
Selbstsynchronisierung ist
Interessanterweise benötigt UTF8 nur 4 Bytes, um alle Unicode-Zeichen zuzuordnen. UTF8 kann jedoch bis zu 68 Milliarden Zeichen unterstützen, falls dies jemals erforderlich sein sollte, wobei bis zu 7 Bytes pro Zeichen benötigt werden.
Santiago Aristi
10

Unicode erlaubt 17 Ebenen mit jeweils 65.536 möglichen Zeichen (oder 'Codepunkten'). Dies ergibt insgesamt 1.114.112 mögliche Zeichen. Derzeit sind nur etwa 10% dieser Fläche zugewiesen.

Die genauen Details, wie diese Codepunkte codiert werden, unterscheiden sich von der Codierung, aber Ihre Frage lässt es so klingen, als würden Sie an UTF-8 denken. Der Grund für Einschränkungen bei den Fortsetzungsbytes liegt vermutlich darin, dass der Anfang des nächsten Zeichens leicht zu finden ist (da Fortsetzungszeichen immer die Form 10xxxxxx haben, das Startbyte jedoch niemals diese Form haben kann).

Simon Nickerson
quelle
Nach diesen "Ebenen" könnten sogar die letzten drei Bytes eines 4-Byte-Zeichens 64 davon ausdrücken. Liege ich falsch?
Ufuk Hacıoğulları
Ja, das ist für die Synchronisation, siehe cl.cam.ac.uk/~mgk25/ucs/utf-8-history.txt
ninjalj
2
Das ist veraltet, denke ich. Es verwendet keine 6 Bytes mehr
Ufuk Hacıoğulları
3
@Andy: Das macht Sinn: Die ursprüngliche Spezifikation für UTF-8 funktionierte für größere Zahlen. Das 21-Bit-Limit war ein Sop für die Leute, die sich in 16-Bit-Zeichen eingeschlossen hatten, und so erzeugte UCS-2 den Gräuel UTF-16.
Tchrist
1
@Simon: Es gibt 34 Nicht-Zeichen-Codepunkte, alles, was bitweise mit 0xFFFE == 0xFFFE hinzugefügt wird, also zwei solcher Codepunkte pro Ebene. Außerdem gibt es 31 Nichtzeichencodepunkte im Bereich 0x00_FDD0 .. 0x00_FDEF. Außerdem sollten Sie die Ersatzzeichen davon abziehen, die aufgrund des UTF-16-Fehlers für den offenen Austausch nicht zulässig sind, aber in Ihrem Programm unterstützt werden müssen.
Tchrist
5

Unicode unterstützt 1.114.112 Codepunkte. Es gibt 2048 Ersatzcodepunkte, die 1.112.064 Skalarwerte ergeben. Von diesen gibt es 66 Nicht-Zeichen, was zu 1.111.998 möglichen codierten Zeichen führt (es sei denn, ich habe einen Berechnungsfehler gemacht).

Philipp
quelle
Kannst du dir meine Antwort ansehen? Warum gibt es 1.112.114 Codepunkte?
Ufuk Hacıoğulları
3
Diese Anzahl ergibt sich aus der Anzahl der Flugzeuge, die mit dem UTF-16-Ersatzsystem adressiert werden können. Sie haben 1024 niedrige und 1024 hohe Surrogate, was 1024² Nicht-BMP-Codepunkte ergibt. Dies plus die 65.536 BMP-Codepunkte ergeben genau 1.114.112.
Philipp
2
@Philipp, aber Sie geben '1_112_114' in Ihrer Antwort an, aber Sie erklären '1_114_112' in Ihrem Kommentar. Vielleicht haben Sie die 2 und 4
verwechselt.
1
Diese Antwort sitzt seit Jahren mit den Berechnungsfehlern herum, deshalb habe ich mir die Freiheit genommen, sie zu bereinigen. Ja, der Wert 1112114 in der Antwort war ein Tippfehler. Der korrekte Wert ist 1114112, was dem Dezimalwert von 0x110000 entspricht.
Ray Toal
1

Um eine metaphorisch genaue Antwort zu geben , all of them.

Fortsetzungsbytes in den UTF-8-Codierungen ermöglichen eine Resynchronisation des codierten Oktettstroms angesichts von "Zeilenrauschen". Der Encoder muss lediglich nach einem Byte suchen, das keinen Wert zwischen 0x80 und 0xBF hat, um zu wissen, dass das nächste Byte der Beginn eines neuen Zeichenpunkts ist.

Theoretisch ermöglichen die heute verwendeten Codierungen den Ausdruck von Zeichen, deren Unicode-Zeichennummer bis zu 31 Bit lang ist. In der Praxis wird diese Codierung tatsächlich in Diensten wie Twitter implementiert, bei denen der Tweet mit maximaler Länge Daten im Wert von bis zu 4.340 Bit codieren kann. (140 Zeichen [gültig und ungültig], mal 31 Bit.)

Andy Finkenstadt
quelle
Tatsächlich ist es theoretisch nicht auf 31 Bit beschränkt, sondern Sie können auf einem 64-Bit-Computer größer werden. perl -le 'print ord "\x{1FFF_FFFF_FFFF}"'druckt 35184372088831 auf einem 64-Bit-Computer aus, führt jedoch auf einem 32-Bit-Computer zu einem Ganzzahlüberlauf. Sie können größere Zeichen wie dieses in Ihrem Perl-Programm verwenden. Wenn Sie jedoch versuchen, sie als utf8 auszudrucken, erhalten Sie eine obligatorische Warnung, es sei denn, Sie deaktivieren Folgendes : perl -le 'print "\x{1FFF_FFFF}"' Code point 0x1FFFFFFF is not Unicode, may not be portable at -e line 1. ######. Es gibt einen Unterschied zwischen "lose utf8" und "strenge UTF-8": Ersteres ist nicht eingeschränkt.
Tchrist
1
Die heute verwendeten Codierungen lassen keine 31-Bit-Skalarwerte zu. UTF-32 würde 32-Bit-Werte zulassen, UTF-8 noch mehr, aber UTF-16 (intern von Windows, OS X, Java, .NET, Python und daher das beliebteste Codierungsschema verwendet) ermöglicht etwas mehr eine Million (was immer noch ausreichen sollte).
Philipp
1
"Alle von ihnen" ist nicht ganz genau; Es gibt Zeichen in Legacy-Codierungen, die nicht in Unicode enthalten sind. Zum Beispiel das Apple-Logo in MacRoman und einige der Grafikzeichen in ATASCII. OTOH gibt es einen Bereich für privaten Gebrauch, so dass diese Zeichen können mit Unicode abgebildet werden; Sie sind einfach nicht Teil des Standards.
Dan04
1
@tchrist: Python 3 verwendet UTF-16; Auf meinem System kann ich beispielsweise sagen len(chr(0x10000)), dass ich 2 (Codeeinheiten) gebe. Der Kernel von OS X verwendet UTF-8, richtig - aber die High-Level-APIs (Cocoa usw.) verwenden UTF-16.
Philipp
1
@Philip: Ich verwende nur Python 2, dessen Unicode-Unterstützung zu wünschen übrig lässt. Ich bin ein System-Typ, daher mache ich keine Chrome-Plattierung für Endbenutzer: Alle Systemaufrufe, die ich unter OS X verwende, verwenden UTF-8, das der Kernel für Sie in NFC konvertiert. Meine UTF-16-Erfahrungen in Java waren schlecht: Versuchen Sie eine Charge-Klassen-Übereinstimmung in Klammern mit wörtlichen Nicht-BMP-Codepunkten [𝒜-𝒵], und Sie werden sehen, warum ich UTF-16 als Pfusch empfinde. Es ist ein Fehler, Programmierer dazu zu bringen, in Codierungsformularen anstatt in logischen Zeichen zu denken.
Tchrist
1

Unicode hat die hexadezimale Menge von 110000, also 1114112

Dmitry Pleshkov
quelle
1

Laut Wikipedia enthält Unicode 12.1 (veröffentlicht im Mai 2019) 137.994 verschiedene Zeichen.

orlp
quelle
@Ufuk: Unicode hat keine Zeichen. Es hat Codepunkte. Manchmal sind mehrere Codepunkte erforderlich, um ein Zeichen zu bilden. Beispielsweise besteht das Zeichen "5̃" aus zwei Codepunkten, während das Zeichen "ñ" ein oder zwei Codepunkte (oder mehr!) Sein kann. Es gibt 2²¹ mögliche Codepunkte, aber einige davon sind als Nichtzeichen oder Teilzeichen reserviert.
Tchrist
6
Unicode ist ein Zeichencodierungsstandard. Erste Antwort von unicode.org/faq/basic_q.html : "Unicode ist die universelle Zeichencodierung", daher ist es falsch zu sagen, dass "Unicode keine Codierung ist". (Ich habe diesen Fehler einmal selbst gemacht.)
Philipp
1
@tchrist: Der Unicode-Standard definiert mehrere Begriffe, darunter "abstraktes Zeichen" und "codiertes Zeichen". Zu sagen, dass Unicode keine Zeichen hat, ist auch nicht wahr.
Philipp