はじめに
URLをコピペしたとき、こんな謎の文字列を見たことはありませんか?
https://ja.wikipedia.org/wiki/%E3%82%A8%E3%83%B3%E3%82%B3%E3%83%BC%E3%83%89
「えっ、ウイルス!?壊れた?」とびっくりした経験があるかもしれません。でも安心してください。これは壊れているわけではなく、「エンコード」 された状態なんです。
普段私たちが使っている日本語や画像などのデータは、そのままではインターネット上でうまく扱えないことがあります。そこで登場するのが「エンコード」と「デコード」という技術です。
この記事では、Web開発をしていると必ず出会うこの仕組みについて、やさしく解説していきます。
エンコード・デコードとは?
一言で言うと、「データを別の形式に変換すること」 と 「元の形式に戻すこと」 です。
引っ越しや宅配便に例えるとわかりやすいかもしれません。
📦 エンコード(Encode)=「梱包」
大切な壺をそのままトラックに放り込んだら割れてしまいますよね。
そこで、段ボールに入れたり、プチプチで包んだりして、「運びやすい形」 に変えます。これがエンコードです。
📤 デコード(Decode)=「開封」
荷物が届いたら、段ボールを開けてプチプチを取り除き、「使える形(元の壺)」 に戻します。これがデコードです。
コンピュータの世界でも同じで、データを安全に通信したり、保存したりするために形を変える必要があるのです。
なぜ必要なの?
「そのまま送ればいいじゃん!」と思うかもしれませんが、コンピュータの世界には「使える文字などのルール」が厳格に決まっている場所があります。
例えば:
- URL: 基本的に半角英数字と一部の記号しか使えません。日本語はNG。
- メール: 昔の仕組みでは画像などのバイナリデータを直接送れませんでした。
-
HTML:
<や>はタグとして認識されるので、文字として表示したい場合は変換が必要です。
これらの「通行できない場所」を通すために、ルールに合った文字だけで表現できるように変換(エンコード)してあげる必要があるのです。
代表的なエンコードの種類
Web開発でよく出会う3つのエンコードを紹介します。
1. URLエンコード(パーセントエンコード)
冒頭で紹介した %E3%81... というやつです。
URLには「日本語やスペースなどの文字」を含めることができません。そこで、それらの文字を % と 16進数 を使った形に変換します。
JavaScriptでの例
ブラウザのコンソールで試してみましょう。
// エンコード(梱包)
const original = "こんにちは";
const encoded = encodeURIComponent(original);
console.log(encoded);
// 出力: %E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF
// デコード(開封)
const decoded = decodeURIComponent(encoded);
console.log(decoded);
// 出力: こんにちは
検索フォームに入力した日本語が、検索結果のURLでおかしな文字列になっているのは、この処理が行われているからなんですね。
2. Base64(ベース64)
これは、画像データなどの「バイナリデータ(0と1の塊)」を、「文字(テキスト)」として扱いたいときによく使われます。
a-z、A-Z、0-9、+、/ の64種類の文字を使ってデータを表現するので「Base64」と呼ばれます。
メールに画像を添付するときや、小さなアイコン画像をHTMLに直接埋め込むとき(Data URI Scheme)に使われます。
JavaScriptでの例
// 文字列をBase64にエンコード
// btoa = binary to ascii
const original = "Hello World";
const encoded = btoa(original);
console.log(encoded);
// 出力: SGVsbG8gV29ybGQ=
// Base64をデコード
// atob = ascii to binary
const decoded = atob(encoded);
console.log(decoded);
// 出力: Hello World
末尾に = がつくのがBase64の特徴です(つかないこともあります)。
3. 文字コード(Character Encoding)
「文字化け」の原因No.1です。
コンピュータは「あ」という文字を理解できません。わかるのは数字(ビット)だけです。
そこで、「『あ』は数字の『12345』番ね!」という対応表を作りました。これが文字コードです。
問題なのは、この対応表が世界にいくつもあることです。
- UTF-8: 今の世界標準。絵文字も世界中の言語も扱える優等生。Webは基本これ。
- Shift_JIS: 昔のWindowsや日本の携帯電話で使われていたもの。
- EUC-JP: 昔のUNIX系OSで使われていたもの。
文字化けの仕組み
- Aさんが UTF-8 で「あ(E3 81 82)」というデータを送る。
- BさんのPCがそれを Shift_JIS だと思って開く。
- Shift_JISの対応表で「E3 81 82」を見ると…「縺」みたいな全然違う文字(または存在しない文字)になる。
- 結果:文字化け発生! 😱
最近のWeb開発では、HTMLのヘッダーに <meta charset="UTF-8"> と書いて、「このページはUTF-8という対応表を使って読んでね!」とブラウザに宣言することで、文字化けを防いでいます。
実践:HTMLエンコード(エスケープ)
最後に、セキュリティ的に超重要な「HTMLエンコード(サニタイズ)」についても触れておきます。
これは、ユーザーが悪意のあるスクリプトを埋め込む攻撃(XSS: クロスサイトスクリプティング)を防ぐために行います。
例えば、掲示板に誰かが <script>alert('乗っ取り!')</script> と書き込んだとします。
これをそのまま表示すると、ブラウザが「おっ、JavaScriptだ!」と認識して実行してしまいます。
これを防ぐために、特別な意味を持つ文字を「無害な文字」に変換します。
-
<→<(less than) -
>→>(greater than) -
"→" -
&→&
こうすると、ブラウザは「ただの文字としての記号」として表示してくれるので、スクリプトは実行されません。
まとめ
- エンコードは、運びにくいデータを運びやすい形に梱包すること。
- デコードは、梱包されたデータを元の形に開封すること。
- URLにはURLエンコード、画像などの埋め込みにはBase64が使われる。
- 文字コード(UTF-8など)の違いが文字化けの原因。
- Web開発者は、データが今「どんな状態で梱包されているか」を意識することが大切!
「なんだか変な文字列になった!」と焦らず、「お、これは何かにエンコードされているな?」と考えられるようになれば、あなたはもう脱初心者です!