LoginSignup
18
13

More than 5 years have passed since last update.

URLエンコード・デコードする

Posted at

Webサーバーログ解析で使いたかった

Webサーバーのログを見ていると、検索ページからジャンプしてきている形跡があった。しかし、検索キーワードはURLエンコードされた状態であり、デコードしないとわからない。果たしてどんなキーワードなのか興味があった。

そこで、FreeBSDのportsに収録されているurlendecというプログラムをサクっとインストールしようとしたら……

32ビット専用だった
# cd /usr/ports/net/urlendec
# make install
===>  urlendec-1.0 is only for i386, while you are running amd64.
*** [install] Error code 1

Stop in /usr/ports/net/urlendec.
# 

これだから、POSIX準拠でないコマンドは信用ならんのじゃ!!!

しょーがないのでデコーダーを自作した

というわけでPOSIX原理主義全開で作った。UNIXならどこでも動くはずなので公開する。必要な方はコピペして使うといい。

urldecode
#! /bin/sh

case $# in
  0) cat -                   ;;
  *) for file in "$@"; do
       case "$file" in
         -)  :             ;;
         /*) :             ;;
         *)  file="./$file";;
       esac
       cat "$file"
     done                    ;;
esac |
exec env - awk '
BEGIN {
  # --- prepare
  LF  = sprintf("\n");
  OFS = "";
  ORS = "";
  # --- prepare decoding
  for (i=0; i<256; i++) {
    l  = sprintf("%c",i);
    k1 = sprintf("%02x",i);
    k2 = substr(k1,1,1) toupper(substr(k1,2,1));
    k3 = toupper(substr(k1,1,1)) substr(k1,2,1);
    k4 = toupper(k1);
    p2c[k1]=l;p2c[k2]=l;p2c[k3]=l;p2c[k4]=l;
  }
  # --- decode
  while (getline line) {
    gsub(/\+/, " ", line);
    while (length(line)) {
      if (match(line,/%[0-9A-Fa-f][0-9A-Fa-f]/)) {
        print substr(line,1,RSTART-1), p2c[substr(line,RSTART+1,2)];
        line = substr(line,RSTART+RLENGTH);
      } else {
        print line;
        break;
      }
    }
    print LF;
  }
}'

GNU版のsedを使えば簡単に書けるのは知っているけど、せっかく作るなら可搬性を高めたいのでPOSIXの範囲で作った。結局AWKにベッタリで、しかも全てをBEGINセクションで済ませるというAWKっぽくない使い方だけど、今回の目的では意味を成さないフィールド分割処理($0,$1,$2,……を作る)が走らないようにするため。

使い方

オリジナルのurldecodeのような各種オプションには対応していないが、変換したいテキストデータを標準入力あるいはファイル(引数で指定)で与えるだけ。簡単でしょ。

ついでにエンコーダーも作った

urlencode
#! /bin/sh

case $# in
  0) cat -                   ;;
  *) for file in "$@"; do
       case "$file" in
         -)  :             ;;
         /*) :             ;;
         *)  file="./$file";;
       esac
       cat "$file"
     done                    ;;
esac |
exec env - awk '
BEGIN {
  # --- prepare
  LF = sprintf("\n");
  OFS = "";
  ORS = "";
  # --- prepare encoding
  for(i= 0;i<256;i++){c2p[sprintf("%c",i)]=sprintf("%%%02X",i);}
  c2p[" "]="+";
  for(i=48;i< 58;i++){c2p[sprintf("%c",i)]=sprintf("%c",i);    }
  for(i=65;i< 91;i++){c2p[sprintf("%c",i)]=sprintf("%c",i);    }
  for(i=97;i<123;i++){c2p[sprintf("%c",i)]=sprintf("%c",i);    }
  c2p["-"]="-"; c2p["."]="."; c2p["_"]="_"; c2p["~"]="~";
  # --- encode
  while (getline line) {
    for (i=1; i<=length(line); i++) {
      print c2p[substr(line,i,1)];
    }
    print LF;
  }
}'

エンコードする必要のない文字(英数字や一部の記号)はそのまま流すようにしてある。

尚、データの与え方はデコーダーと同じ。

18
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
13