Thread Surrogate Pairs in UTF-8 auflösen (28 answers)
Opened by barney at 2025-08-14 14:22

rosti
 2025-08-17 10:50
#197220 #197220
User since
2011-03-19
3688 Artikel
BenutzerIn
[Homepage]
user image
Der Algorithmus ist auch in Perl umsetzbar. Du bekommst mit

Code (perl): (dl )
1
2
3
# ED A0 BD ED B8 80
my $bin = pack "C*", 0xED, 0xA0, 0xBD, 0xED, 0xB8, 0x80; 
my @cps = unpack "U*", decode_utf8 $bin; # D83D DE00


Die High- und Low-Surrogate aus der Binary. Die erkennst Du daran, daß sie in einem Range von D800-DBFF (High) und DC00-DFFF (Low) liegen. Dieser Range ist in UNICODE dafür reserviert.

Weiter gehts:
Vom High-Surrogate 0xD800 abziehen und vom Low-Surrogate 0xDC00 abziehen. Also jeweils die untere Grenze der Ranges. Dann wird $H mit 0x400 multipliziert, $L addiert und nochmal 0x10000 dazu addiert. So kommst Du auf 1F600, den Codepoint im UNICODE für das GRINNING FACE (Fratze).

Code (perl): (dl )
1
2
3
my $H = 0xD83D - 0xD800; # High Surrogate
my $L = 0xDE00 - 0xDC00; # Low Surrogate
printf "%X", $H * 0x400 + $L + 0x10000; # 1F600



Nun, obenstehend bekommen wir in @cps genau 2 dieser Surrogate-Codepoints. Bei längeren Texten sind das natürlich mehr als nur 2. Alles in Allem wäre @cps also CP für CP durchzugehen um zu gucken ob sich darin diese reservieren Surrogate-Codepoints befinden. Sobald einer gefunden wird der in D800-DBFF liegt, schnappen wir uns alle Beide und wenden den Algorithmus (siehe oben) an, also tausch High und Low-Surrogate gegen diesen einen CP aus.

Schließlich wird mit pack "U*", @korrigierte_codepoint_liste; eine Binary erzeugt, mit Zeichen die korrekt UTF-8 kodiert sind.

Alles zusammen nach dem Kaffe ;)
http://blog.rolfrost.de/

The art of steam.

View full thread Surrogate Pairs in UTF-8 auflösen