ASP.NET で Web アプリケーションを書いていると、文字列をエンコードしないといけないことがよくあります。HTML の中には < や > といった記号は書けないので < と > に変換しないといけないだとか、URL の中に半角スペースは入れられない(?)ので %20 に変換しないといけないだとかいったルールがすぐに思い浮かびます。ほかにも Base64 エンコーディングなんかもありますね。
ASP.NET というか .NET Framework には、これらの処理を行うためのメソッドが用意されています。
その中でも、今回取り上げたいのは System.Web.HttpServerUtility クラスのメソッド、UrlEncode() と HtmlEncode() です。
私は今まで、これらの違いをよくわからずに使っていました。
「HTML の中に書く文字列だから HTML エンコードしとこ」とか、「URL にくっつける文字列だから URL エンコードでいいだろう」といった基準でどちらを使うか決めていました。
基本的にはそんな感じの使い分け方でもいいのかもしれませんが、これらのメソッドが具体的にどの文字をどういうふうにエンコードしてくれるのか、ちょっと気になったので調べてみました。
Web アプリケーションプロジェクトを新規作成して、以下のようなコードを書いて実行してみました。
protected void Page_Load(object sender, EventArgs e)
{
for (int i=0; i<128; i++)
{
char c = Convert.ToChar(i);
Debug.WriteLine(string.Format("{0} => {1}, {2}", c, Server.HtmlEncode(c.ToString()), Server.UrlEncode(c.ToString())));
}
}
結果を表形式でまとめると、以下のようになります。
| 文字 |
HEX |
HtmlEncode |
UrlEncode |
| 制御文字 |
0x00 - 0x1f |
そのまま |
%00 - %1f |
| (半角スペース) |
0x20 |
(半角スペース) |
+ |
!
|
0x21 |
! |
! |
| " |
0x22 |
" |
%22 |
| # |
0x23 |
# |
%23 |
| $ |
0x24 |
$ |
%24 |
| % |
0x25 |
% |
%25 |
| & |
0x26 |
& |
%26 |
| ' |
0x27 |
' |
' |
| ( |
0x28 |
( |
( |
| ) |
0x29 |
) |
) |
| * |
0x2a |
* |
* |
| + |
0x2b |
+ |
%2b |
| , |
0x2c |
, |
%2c |
| - |
0x2d |
- |
- |
| . |
0x2e |
. |
. |
| / |
0x2f |
/ |
%2f |
| 0 - 9 |
0x30 - 0x39 |
0 - 9 |
0 - 9 |
| : |
0x3a |
: |
%3a |
| ; |
0x3b |
; |
%3b |
| < |
0x3c |
< |
%3c |
| = |
0x3d |
= |
%3d |
| > |
0x3e |
> |
%3e |
| ? |
0x3f |
? |
%3f |
| @ |
0x40 |
@ |
%40 |
| A - Z |
0x41 - 0x5a |
A - Z |
A - Z |
| [ |
0x5b |
[ |
%5b |
| \ |
0x5c |
\ |
%5c |
| ] |
0x5d |
] |
%5d |
| ^ |
0x5e |
^ |
%5e |
| _ |
0x5f |
_ |
_ |
| ` |
0x60 |
` |
%60 |
| a - z |
0x61 - 0x7a |
a - z |
a - z |
| { |
0x7b |
{ |
%7b |
| | |
0x7c |
| |
%7c |
| } |
0x7d |
} |
%7d |
| ~ |
0x7e |
~ |
%7e |
| 制御文字 |
0x7f |
そのまま(?) |
%7f |
元の文字から何らかの変換が行われる部分は背景をピンク色にしてみました。
比較すると、HTML エンコードのほうは基本的に " & < > の 4 文字だけを &~; という形に変換していまが、それ以外はそのまま無変換です。
URL エンコードのほうは、基本的に 0-9, A-Z, a-z の英数字といくつかの記号を除いてはほとんど %xx という形に変換しています。半角スペースが + 記号に変換されるのは特殊なルールという感じですね。
さらに、0x80 以降についても見てみました。
HTML エンコードは 0x80 - 0x9f までの文字はそのまま出力しますが、0xa0 - 0xff は  、¡ ・・・ ÿ という形式にエンコードされるようでした。それ以降(0x100 以降)はふたたび文字がそのまま出力されているようでした。
URL エンコードは、0x80 以降の文字はすべて、いったん UTF-8 エンコードしたものをさらに %xx 形式でエンコードしているようです。0x80 = %c2%80, 0x81 = %c2%81, ... となります。
(先に UTF-8 エンコードするのは .NET Framework の仕様かもしれません。また、Shift-JIS や EUC でエンコードするように変更する方法があるかもしれません。)
いままであいまいだった部分が少しわかった気がしてすっきりしました。