Ziel ist es, einen vollständig kompatiblen Konverter zwischen den offiziellen Unicode-Codierungen zu erstellen, wie in den UTF-FAQ angegeben . Da dies auf Unicode zentriert ist, akzeptiere ich die Antwort mit der niedrigsten Byteanzahl unter Verwendung der bestmöglichen der beteiligten Codierungen (die wahrscheinlich UTF-8 sein wird, es sei denn, Sie programmieren sie in APL). Ich entschuldige mich für den langen Beitrag, aber ein Großteil davon erklärt die Kodierungen, auf die auch in der offiziellen Spezifikation (pdf, Abschnitt 3.9 D90 - D92) oder in Wikipedia zugegriffen werden kann .
Spezifikationen
Wenn Ihre gewählte Sprache zu irgendeinem Zeitpunkt eine Anforderung nicht genau erfüllen kann, ersetzen Sie sie durch etwas, das dem Geist der angegebenen Regeln entspricht. Z.B. Nicht jede Sprache verfügt über eingebaute Arrays, Funktionen usw.
Verwenden Sie keine Zeichenfolgenbibliotheken / -funktionen oder Kodierungsbibliotheken / -funktionen. Der Sinn dieses Codegolfs besteht darin, den Konverter unter Verwendung von Bit / Byte-Manipulation zu implementieren. Die Verwendung von Strings selbst als Zeichen- oder Byte-Array ist jedoch zulässig. Oh, und auch keine OS-Aufrufe, die die Konvertierung durchführen.
Der Konverter ist eine Funktion, die drei Parameter akzeptiert: ein Byte-Array, das die codierte Eingabezeichenfolge darstellt, und die als Zahlen dargestellten "Eingabe" - und "Ausgabe" -Codierungen. Beliebig vergeben wir
UTF-8, UTF-16, UTF-16BE, UTF-16LE, UTF-32, UTF-32BE, and UTF32LE
Nummern von 0 bis 6 in dieser Reihenfolge. Es muss nicht überprüft werden, ob die Zahl< 0
oder> 6
ist. Wir gehen davon aus, dass diese Parameter korrekt sind. Der Konverter gibt ein gültiges Byte-Array in der gewünschten Ausgabecodierung zurück.Wir werden das Nullzeichen (
U+0000
) als Zeichenkettenabschluss verwenden. Alles was danach passiert ist egal. Wir gehen davon aus, dass das Eingabearray irgendwo das Null-Zeichen hat, sodass Sie keine Begrenzungsprüfung durchführen müssen.Laut FAQ müssen wir einen Fehler melden , wenn das Eingabebyte-Array für seine deklarierte Codierung ungültig ist. Wir werden dies auf eine der folgenden Arten tun: Absturz des Programms, Auslösen einer Ausnahme, Zurückgeben von Null oder Zurückgeben eines Arrays, dessen erste vier Bytes alle 0 sind (damit es wie
U+0000
in jeder Codierung erkannt werden kann ).
Die Kodierungen
Die offiziellen Spezifikationen müssen befolgt werden, aber Wikipedia bietet eine gute (und meines Erachtens korrekte) Erklärung der Kodierungen, und der Vollständigkeit halber werde ich sie hier zusammenfassen. Beachten Sie, dass UTF-16 und UTF-32 Varianten für Endianness haben .
UTF-32, UTF-32LE, UTF-32BE
Bei der einfachsten Codierung wird jeder Codepunkt einfach in 4 Bytes entsprechend seinem numerischen Wert codiert. LE / BE steht für Endianness (Little Endian / Big Endian).
UTF-16, UTF-16LE, UTF-16BE
Codepunkte von U+0000 - U+FFFF
werden in 2 Bytes entsprechend ihrem numerischen Wert codiert. Größere Werte werden mit einem Paar Ersatzzeichen codiert, die reservierte Werte von sind U+D800 - U+DFFF
. Um Punkte zu kodieren U+FFFF
, die größer als sind , kann der folgende Algorithmus verwendet werden (unverschämt aus Wikipedia kopiert ):
- 0x010000 wird vom Codepunkt abgezogen, wobei eine 20-Bit-Zahl im Bereich von 0..0x0FFFFF verbleibt.
- Die oberen zehn Bits (eine Zahl im Bereich 0..0x03FF) werden zu 0xD800 hinzugefügt, um die erste Codeeinheit oder den ersten Ersatz zu erhalten, der im Bereich 0xD800..0xDBFF [...] liegt.
- Die unteren zehn Bits (ebenfalls im Bereich 0..0x03FF) werden zu 0xDC00 addiert, um die zweite Codeeinheit oder den zweiten Ersatz zu ergeben, der im Bereich 0xDC00..0xDFFF [...] liegt.
UTF-8
Codepunkte von U+0000 - U+007F
werden als 1 Byte entsprechend ihrem numerischen Wert codiert. Von U+0080 - U+07FF
sie als codiert sind 110xxxxx 10xxxxxx
, U+0800 - U+FFFF
ist 1110xxxx 10xxxxxx 10xxxxxx
, sind höhere Werte 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
. Die x
‚s sind die Bits aus dem numerischen Wert des Codepunktes.
Stückliste
Die Bytereihenfolge-Markierung (BOM U+FEFF
) wird als erster Codepunkt verwendet, um die Endianität anzuzeigen. Gemäß den FAQ-Richtlinien zu Stücklisten wird die Stückliste wie folgt verwendet: UTF-8, UTF-16 and UTF-32
Sie ist optional. Fehlt die Stückliste in UTF-16
oder UTF-32
, wird von einem Big Endian ausgegangen. Die Stückliste darf nicht in erscheinen UTF-16LE, UTF-16BE, UTF-32LE and UTF-32BE
.
Häufige Fehler, die zu ungültigem UTF führen
Verschiedene Dinge können dazu führen, dass eine Byte-Sequenz ungültiges UTF ist.
- UTF-8 und UTF-32: Direktes Codieren von Ersatzcodepunkten (
U+D800 - U+DFFF
) oder Codepunkten größer alsU+10FFFF
. - UTF-8: Viele ungültige Bytefolgen.
- UTF-16: Nicht gepaarte oder falsch gepaarte Ersatzzeichen.
- Stückliste: Muss wie im Codierungsabschnitt angegeben verwendet werden. Beachten Sie, dass Sie bei der Ausgabe
UTF-16
oderUTF-32
(ohne Angabe einer inhärenten Endianzahl) auswählen können, bei Little Endian jedoch die Stückliste einbeziehen müssen.
Beachten Sie, dass Nicht-Zeichen und nicht zugewiesene Codepunkte (beide von Surrogaten verschieden) wie normale Zeichen behandelt werden.
''⎕R''⍠'InEnc' 'UTF16BE' 'OutEnc' 'UTF8-BOM'
.