小池啓仁 ヒロヒト応援ブログ By はてな

小池啓仁(コイケヒロヒト)の動画など。

小池啓仁 ヒロヒト応援ブログ By はてな

URLデコード処理

URLデコード処理とは、CGIで標準入力からHTMLフォームデータを読み込む時の定石の処理です。

    @pairs = split(/&/,$buffer);
    foreach $pair (@pairs) {
        ($name, $value) = split(/=/, $pair);
        $value =~ tr/+/ /;
        $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
        $FORM{$name} = $value;
    }

$buffer変数内では、『要素名1=データ1&要素名2=データ2&..要素名N=データN』のデータ並びを想定します。
これは、CGIでHTMLのフォームデータを標準入力から読み込んだデータ並びです。
これを、『&』デリミタでsplitし、『要素名=データ』毎の配列『@pairs』を作成し、
つぎに、『@pairs』の配列数分foreachし、『@pairs』の要素を、『=』デリミタでsplitし、要素名とデータを取得します。
尚、データは、URLエンコードされています。

「URLエンコード」とは
A〜Z、a〜z、0〜9、* - . @ _ はそのまま。
半角スペースは + に変換。
その他はすべて % に16進の2桁の文字コード
たとえば、「あ」0x2422なら %24%22になります。

今回は、デコードなので上記の反対を行います。
『$value =~ tr/+/ /;』は、『+』を半角スペースに戻します。
trは、変換演算子といい、置換演算子のsと違い正規表現は使えません。

『%([a-fA-F0-9][a-fA-F0-9])』は、漢字等のエンコード状態で、(〜)による記憶で16進値をあらわす文字列が$1へ渡されます。
これをhex関数で10進数の数値にし、pack関数でその数値を文字コード1文字に変換します。
結果的に、この1文字へ16進数値をあらわす文字列(%24等)が『s///eg』で変換されるわけです。

尚、g指定は『$value』全体に適用します。
また、e指定は置換文字列『pack("C", hex($1))』を式として評価した結果を対象にすることです。
これがないと『pack("C", hex($1))』の文字列で置換してしまいます。

そして、ハッシュ『%FORM』へ要素名がキーになったデータを格納することができました。