( Xanco | 2014. 07. 15., k – 23:07 )

Ha már így kérded, igen, végigolvastam.

Ha részletesebb magyarázatot szeretnél, akkor íme:

Az LWP::Simple szintén az LWP-t használja, a választ tartalmazó HTTP::Response objektum a decoded_content() függvényével adja vissza a letöltött tartalmat. A decoded_content valójában a HTTP::Message modulban van megvalósítva. A kapott választ a Content-Type válaszfejlécben szereplő karakterkódolással, annak hiányában alapértelemezetten a "natív" "ISO-8859-1" kódolással értelmezi és ha van benne az \x00-\x7f tartomány kívül is karakter, akkor az utf8::upgrade függvénnyel alakítja a perl belső unicode string formátumára.

A mi esetünkben a letöltött tartalom bináris, szinte biztosan van benne 7 biten kívül eső karakter, ezért szinte biztosan unicode stringként kapjuk vissza (hint: Encode::is_utf8 függvénnyel tesztelhető). Amikor :raw módoban fájlba írjuk ki, akkor a unicode string visszaalkításra kerül egyszerű ISO-8859-1 kódolt bájtszekvenciává. Utána ezt a bájtszekvenciát :raw módoban olvassuk vissza, akkor már nem unicode stringet kapunk eredményül, hanem megmarad egyszerű bájtszekvenicaként, ISO-8859-1 stringként.

A Crypt::CBC decrypt függvénye kapott adatot pack() függvénnyel és "a" templatetel alakítja paddolt bájt blokkokká. Ha unicode stringet kap paraméterül, akkor a pack "a" templateje csak az alsó 8 bitjét veszi figyelembe az egyes unicode karaktereknek és csak ezeket használja adatként a kódoláshoz. Ha viszont korrektül a bájtszekvenciát kapja meg, akkor a unicode karakterek UTF-8 bájtszekvenciáját kódolja el.

Ezért lényeges, hogy kódoláshoz sose használjunk perles unicode stringet, hanem mindig csak szigorúan bájtszekvenciát (a kívánt kódolás mellett). Bináris adatot pedig végképp szerencsétlen unicode stringként tárolni, hiszen nincsen és sosem volt karakterkódolása, ami alapján értelmezni lehetett volna benne a karaktereket (hát hacsaknem tényleg a latin1/iso-8859-1). Ezért javasolom, hogy kényszerítsük az LWP tartalomnál a karakterkódolás ignorálását és kérjük szépen csak vissza a kapott bájtsorozatot, hiszen valójában erre van szükségünk. Utána már ennek a decryptálása is helyes lesz.