|
Mit freundlicher Unterstützung von:![]()
|
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
|
the choice of a gnu generation linux user group austria; |
Suche
|
Letzte Änderung:
webmaster@luga.at September 2010 |