[LUGA] Mit freundlicher Unterstützung von:
Linux New Media AG

Mail Thread Index


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [luga] Perl UTF8 nochmal ...



On 2007-03-03 17:00:05 +0000, Goesta Smekal wrote:
>   der Erfolg von Peters Rat zu meiner letzten Anfrage war leider nicht
> von großer Dauer. Ich kann jetzt zwar korrektes Patternmatching mit UTF8
> Zeichen machen und auch Scripst schreiben, die UTF8 korrekt einlesen und
> ausgeben, mit der internen Verarbeitung hakt es aber noch:
> 
> binmode(STDOUT, ":utf8");
> binmode(STDIN, ":utf8");
[...]
>       print "$fieldname[$c]:: ".MIME::Base64::encode(encode("utf8",
> $val));
>       print "$fieldname[$c]:: ".encode("utf8", $val); # zur Kontrolle
[...]

> So. Und wenn ich jetzt mein Script aufrufe: "./user-ldif.pl >
> user.ldif" dann kommen in die gecos Zeilen, die nicht Base64 codiert
> sind _vier_ Byte pro Sonderzeichen:
> 
> eine Zeile aus user_utf8.csv:
> p2scwo;1014;100;.........mül............;/home/......;/bin/sh;AT;Partner
> 
> in Hex:
> 00000000  70 32 73 63 77 6f 3b 31  30 31 34 3b 31 30 30 3b 
> |p2scwo;1014;100;|
> 00000010  .. .. .. .. .. .. .. ..  .. 6d c3 bc 6c .. .. ..  
                                        m  ü     l

					Passt.
> 
> Die (nicht codierte) Zeile im LDIF:
> 00000000  67 65 63 6f 73 3a 3a 20  .. .. .. .. .. .. .. ..   |gecos::
> .......|
> 00000010  .. 6d c3 83 c2 bc 6c ..  .. .. .. ..  .. .. .. ..   |.m....l...
> ....|
> 00000020  .. .. ..  68 6f 6d 65 44  69 72 65 63 74 6f 72 79 
> |...homeDirectory|
> 00000030  3a 20 2f 68 6f 6d 65 2f  .. .. .. .. .. ..  6f 0a     |:
> /home/.......|
> 0000003f
> 
> Woher kommen jetzt die vier Byte "c3 83 c2 b2" ?
                                             ^^
					     bc

Double encoding: Du kodierst einmal explizit im Programm:

>       print "$fieldname[$c]:: ".encode("utf8", $val); # zur Kontrolle

und dann implizit noch einmal bei der Ausgabe:

> binmode(STDOUT, ":utf8");

Dadurch wird aus "...m\x{FC}l..." zuerst "...m\x{C3}\x{BC}l..." und dann
"...m\x{C3}\x{83}\x{C2}\x{BC}l...".

Der base64-kodierte String stimmt aber:

% echo Li4uLi4uLi4ubcO8bC4uLi4uLi4uLi4uLg | base64 -d  | hd
00000000  2e 2e 2e 2e 2e 2e 2e 2e  2e 6d c3 bc 6c 2e 2e 2e
|.........m..l...|
00000010  2e 2e 2e 2e 2e 2e 2e 2e  2e                       |.........|
00000019

Für Debug-Ausgaben bei Unicode-Problemen ist es oft sinnvoll, den String
gleich in Hex auszugeben:

    print +(map sprintf("%x ", ord($_)), split(//, $string)), "\n";

oder manchmal sogar:

    use charnames ();

    print +(map {"(@{[charnames::viacode(ord($_))]}) "} split(//, $string)), "\n";

(in Deinem Fall allerdings nicht, weil Dich ja tatsächlich die "Bytes"
interessieren und nicht die "Zeichen")

> Laut Unicode Tabelle für Latin1 bedeutet "c3 83" NBH oder "no break
> here" und "c2 b2" ist IMHO _nicht_ UTF8.

"C2 B2" wäre die korrekte Kodierung von U+00B2 (SUPERSCRIPT TWO), aber
es ist ohnehin "C2 BC" (U+00BC VULGAR FRACTION ONE QUARTER).

	hp

-- 
   _  | Peter J. Holzer    | Ich sehe nun ein, dass Computer wenig
|_|_) | Sysadmin WSR       | geeignet sind, um sich was zu merken.
| |   | hjp@hjp.at         |
__/   | http://www.hjp.at/ |	-- Holger Lembke in dan-am

Attachment: signature.asc
Description: Digital signature



powered by LINUX the choice of a gnu generation
linux user group austria;
Suche
Suche
Letzte Änderung:
webmaster@luga.at
September 2010