URLデコードするソースを解説 - URLデコードとは?

このQ&Aのポイント
  • URLデコードするソースの機能は「URLデコード」であり、エンコードされた日本語文字を読める文字に変換するものです。
  • ソースコードの処理は、正規表現を使ってURLのエンコードされた文字列を特定し、hex関数とpack関数を組み合わせて変換しています。
  • hex関数は16進数を10進数に変換する関数であり、pack関数はバイナリ体構造体に変換する関数です。バイナリ体構造体はデータの形式を指定するためのもので、2進数表現を含むこともあります。
回答を見る
  • ベストアンサー

URLデコードするソースですが、。。。

分かる方、ぜひ教えていただきたいです。 CGI掲示板を作っていますが、 参考書に次のソースが載っており、 $val =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; それの機能は「URLデコード」だそうです。 多分、エンコードでわけのわからなくなった日本語文字(%98%45%83など)を ちゃんと読める文字にしてくれる機能だろうとは理解していますが。。。 上のソースをリファランスなどで調べたところ、 「hex()は16進数を10進数に変換する関数」で、 「pack()はバイナリ体構造体に変換する関数」とかいてありますが、 バイナリ体構造体??何それ???って感じです。バイナリって2進数ですよね? 日本語ってバイナリですか。どうも正確な意味が分かりません。 どなたか分かりやすい解説をお願いいたします。

  • CGI
  • 回答数2
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
  • duckling
  • ベストアンサー率47% (88/185)
回答No.2

# 1 です。 意味は理解していても深く考えたことはなかったのですが なかなかいい機会なのかも知れません。(笑 $val =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; sjisで[あ]を送信すると、[%82%A0]が送られるのですが、 変換を「式として評価」する 修飾子「e」があれば、 「あ」が出力されます。 まぁ、これがURLデコードってヤツですよね。 しかし修飾子「e」が無ければ、 [pack("C", hex(82))pack("C", hex(A0))] が出力されます。 これを見れば「式として評価」と言う意味が分かるのではないかと。 s で何を行っているかというと、「pack("C", hex(16進数))」という 「ただの文字列」に置換しているわけです。 置換された文字が「式」じゃないとすれば、置換したそのままが出ます。 しかし「式」なら、 置換に加えてさらに pack("C", hex(16進数)) が実行されます。 URLエンコードされた時に バイナリデータ → 10進数 → %+16進数2文字 という形で送られて行くので、 それを元に戻すために、 エンコードされた時の逆をやっているということです。 ということで、 これ見て「ここは違うぞ」と思われた方、 遠慮無くツッコミ下さい。(笑

cgi_syoho
質問者

お礼

本当に心からお礼申し上げます。どうもありがとうございました。 おかげさまでこれからは自信を持って質問させていただいたソースが使えそうです。 目下本格的にCGIを勉強中であり、たくさんの壁があるとは思いますが、ducklingさんのような親切な方がいらっしゃるとすごく心強いですね。 また何かと機会がありましたら、どうぞよろしくお願いいたします。

その他の回答 (1)

  • duckling
  • ベストアンサー率47% (88/185)
回答No.1

%([a-fA-F0-9][a-fA-F0-9]) ↑ここから切り出した $1に16進数で2文字(1byte)の値が入るので、 「hex」で10進数に変換し、 それを「pack」が第一引数の「C(符号無しキャラクタ)」という変換方法により、 第二引数の10進数の数字をバイナリデータに変換するのです。 修飾子 g がマッチするもの全てを変換し、 %+2桁 にマッチしなかったものは変換されずにそのまま残ります。 そして 修飾子 e が、置き換える文字列を「式」として認識します。 書いてるうちに疲れてきたので、(爆 残りは他の人に任せます。

cgi_syoho
質問者

お礼

ほぼ理解できました。16進数→1進数→2進数(バイナリ)の順になっていくのですね。(もしかして勘違い?) この度はお疲れのところ、丁寧な解説をいただきましてどうもありがとうございました。 ちょっと疑問ですが、修飾子eですが、これを省くと(式として認識させないと)どうなるんでしょうか。他の方でもかまいませんので、教えていただけたら本当にありがたいです。 どうぞよろしくお願いいたします。

関連するQ&A

  • フォームデコード

    よく見かける $value =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C", hex($1))/eg; というやつの pack("C", hex($1)) を chr($1) にした方がいい と思ったんだけど、chr($1) のソースは見たことがないです。 chr($1) にするとうまくいかない場合があったりするんですか?

    • ベストアンサー
    • CGI
  • デコード処理部分のプログラムについて

    デコード処理部分のプログラムで分からないトコがあるので教えてください。 $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; &jcode'convert(*value,'euc'); この『pack("C", hex($1))』、『eg』の部分の意味がよく分かりません。 『&jcode'convert(*value,'euc');』の部分も微妙なので、お願いします。

    • ベストアンサー
    • Perl
  • デゴートについて

    初心者です。お願いいたします。 デゴートについての基礎を学んでいるのですが 行き詰っています。 $value=~s/%([a-fa-F0-9][a-fA-F0-9])/pack('C',hex($1) )/ge; という文なのですが、この解釈の仕方がイマイチ分かりません。 ●s/// = 置き換え演算子 ●『%([a-fa-F0-9][a-fA-F0-9])』を『pack('C',hex($1))』 に変換する ●hex関数 = 16進数に変換する ・・・と自力で少し理解してみたのですが、参考書によると、hex関数で16進数を10進数に変換する・・と逆のことが書いてあるんです(TT) それと最後の『ge』とはどういう意味なのでしょうか。 理解不足で申し訳ないのですが、どなたか詳しい方、アドバイスいただければ助かります。お願いいたします。

    • ベストアンサー
    • CGI
  • デコードできない時があります><

    なぜか「ひらがな」を偶数個送るとデコードしません 例 「あ」→「あ」 「ああ」→「縺ゅ≠」 「ああい」→「ああい」 「ああいい」→「縺ゅ≠縺・>」 「ああ質問」→「ああ質問」 「ああアあ」→「ああアあ」 今の所漢字やカナを含めて偶数個では問題無いです。 use lib './lib'; use Jcode; read(STDIN, $POST, $ENV{'CONTENT_LENGTH'}); @_post = split (/&/,$POST); foreach $tmp (@_post) { ($name,$value) = split (/=/,$tmp); $value=~s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; Jcode::convert($value,"sjis"); $box{$name} = $value; } デコード処理はこんな感じです。 JcodeはJcode-2.07を使ってます。 独自で色々調べたのですが解決策が見つからず大変困っております。 宜しくお願いします。

    • 締切済み
    • CGI
  • UTF-8から送信されたデータを日本語化するには?

    %E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A これを あいうえお に変換するには、どのようにデコードすればいいのでしょうか? ご教授お願いします。m(_ _)m [現在のソース] $buffer = $ENV{'QUERY_STRING'}; @pairs = split(/&/,$buffer); foreach $pair (@pairs){ ($name, $value) = split(/=/, $pair); $name =~ tr/+/ /; $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; my $value = Jcode::convert($value, 'utf8'); $FORM{$name} = $value; } ↓ 「縺ゅ>縺・∴縺・」が検出されます。

    • ベストアンサー
    • Perl
  • URLのUTF-8からShift-JISへのデコード

    CでUTF-8からShift-JISへのデコードを行うプログラムを 標準関数を使って作りたいのですが、どう行ったらいいのかわかりません。 例えば /f%e3%83%86%e3%82%b9%e3%83%88%e3%81%a7%e3%81%99.txt というURLを入力したら、 /テストです.txt という日本語入りのURLに変換して、 最終的にはその日本語ファイルのオープンを行いたいです。 参考になるHPやソースがありましたら、教えていただけないでしょうか?

  • URLデコードをしてくれるリネームソフトを探しています

    URLデコードをしてくれるリネームソフトを探しています URLエンコードされた名前のファイル名があるのですが、これを日本語のファイルに直したいです ファイル数が結構あり、手で直すのはちょっと無理があるのでURLデコードをしてくれるリネームソフトを探しています 文字コードはUTF-8です よろしくお願いします

  • CGIデコードでつまづいています。

    PerlCGIのデコードでつまづいています。jcode.plで$valueの値を「%E3%81%BF%E3%81%AE%E3%82%8A%E5%8F%B0」から「みのり台」の日本語に変換しようとしたのですが「%E3%81%BF%E3%81%AE%E3%82%8A%E5%8F%B0」が返されてうまくいきません。申し訳ありませんが知恵を貸して頂けないでしょうか、よろしくお願い致します。 #!/usr/bin/perl require './jcode.pl'; #デコードするためのプログラム # プラウザからのデータ取込み #if ($ENV{'REQUEST_METHOD'} eq "POST") { # read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); #} #else { $buffer = $ENV{'QUERY_STRING'}; #} # プラウザからのデータ変換 #$i = 0; #※2 @pairs = split(/&/,$buffer); foreach $pair (@pairs) { #1行毎に$name,$valueを取り出す ($name, $value) = split(/=/, $pair); # 変換演算子 tr + を スペースに置き換え # $value =~ tr/+/ /; # 変換演算子 s/// 単語の構成文字にマッチ # $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; # " を &quot; に変換 # $value =~ s/"/&quot;/g; #\n を "" に変換 # $value =~ s/\n//g; print qq(   <tr><td>やった</td></tr>   ) , "\n"; # jcodeでデコードがうまく出来ませんでした。 # 日本語に変換(デコード処理部分) &jcode'convert(*value,'sjis'); &jcode'convert(*$name,'sjis'); # $FORM{$name} = $value; #※1 # @num[$i]=$value; #※2 # $i=$i++; #※2 # $str = decode('shiftjis', $value); # $value = encode('shiftjis', $str); } @varuee = split(/&*q=/,$ENV{'QUERY_STRING'}); print qq(   <HTML>   <HEAD>   <TITLE>画像の検索結果</TITLE>   </HEAD>   <BODY bgcolor="#FFFFFF">  <H2 align="center">画像データベースの検索結果</H2>  <!--画像の検索結果を2~3件ためしに表示-->  <BR>   <hr>   <CENTER>   <table> ); print qq(   <tr><td>$value</td></tr>   ) , "\n"; exit;

    • ベストアンサー
    • Perl
  • デコードフォームについて。

    以下のスクリプトについて質問があります。かなり多いのですが・・・ sub DecodeForm #返り値:Name=>Val のハッシュ(グロブ) #使用例:*form = EncodeForm(); print $form{name}; { my($encoding) = @_; my($method) = $ENV{'REQUEST_METHOD'}; local($query, @in, $key, $val); require 'jcode.pl' if $encoding; if ($method eq 'GET') { $query = $ENV{'QUERY_STRING'}; } elsif ($method eq 'POST') { read(STDIN, $query, $ENV{'CONTENT_LENGTH'}); } local(@query) = split(/&/, $query); foreach (@query) { tr/+/ /; ($key, $val) = split(/=/); # %HH形式を元の文字にデコードする。 $key =~ s/%([A-Fa-f0-9][A-Fa-f0-9])/pack("c", hex($1))/ge; $val =~ s/%([A-Fa-f0-9][A-Fa-f0-9])/pack("c", hex($1))/ge; $val =~ s/\r\n/\n/g; jcode'convert(*key, $encoding) if ($encoding); jcode'convert(*val, $encoding) if ($encoding); $in{$key} = $val; } return *in; } 多いので先頭から順に箇条書きにさせて頂きます。 ・Name=>Val の意味。(#以下がメモであることは分かっています) ・グロブとは何か ・*form = EncodeForm(); print $form{name}; の意味。(特に、先頭の*が分かりません) ・my $encoding という変数も見たことがあるのですが、my($encoding) と my $encoding はどう違うのか。 ・クエリとは何か ・jcode.pl とは、インストールしたPerlに標準でついているライブラリなのか?そうでないのならjcode.plとは何か? ・%HH形式とは何か ・\rの意味 ・jcode'convert の意味 ・*key の * の意味 ・*in の * の意味 多くて申し訳ないです。分かる方いらっしゃいましたご教授くださると幸いです。よろしくお願いします。

    • ベストアンサー
    • Perl
  • PerlプログラムをPHPで書き直しています

    Perlで作ったものをPHPで書き直しています。 似てるようで大変ですね。 $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; という表現ですが、これをPHPで書き直すとズバリどのように なりますか? ちなみにPERLのソースコードでは、このあと &jcode'convert(*value,'sjis'); になるのですが、PHPでPerlのこの変換を実現する一般的方法が あったら教えてください。その方法で全部書き直そうと思います。

    • ベストアンサー
    • PHP