@nqounetです。
連載「URL短縮サポーターを作ってみよう」の第4回です。
前回の振り返り
第3回では、フォームから送信されたURLをサーバー側で受け取る処理を実装しました。
前回学んだ内容を簡単に振り返ります。
post '/shorten' => sub ($c) { ... };でPOSTルーティングを定義した$c->param('url')でフォームから送信されたパラメータを取得した- 受け取ったURLを画面に表示して動作確認した
今回は、受け取ったURLから「短縮コード」を生成する仕組みを学びます。
今回のゴール
第4回では、以下を達成することを目標とします。
- ハッシュ関数の仕組みを理解する
- Digest::SHAを使ってURLから短縮コードを生成する
- メモリ上で仮実装し、動作確認する
どうやって短いコードを作る?
タカシさんの疑問
前回、タカシさんが入力したURLを受け取れるようになりました。タカシさんは画面を見ながらこう尋ねます。
「受け取ったURLを、どうやって短いコードに変換するの?」
良い質問です。長いURLから短い識別子を作るには、いくつかの方法が考えられます。
- 連番(1, 2, 3…)を発行する
- ランダムな文字列を生成する
- URLをハッシュ化する
今回は、3番目の「ハッシュ化」を採用します。
ハッシュ関数とは
ハッシュ関数とは、任意の長さのデータから固定長の文字列(ハッシュ値)を生成する関数です。以下の特徴があります。
- 同じ入力からは常に同じハッシュ値が生成される
- 異なる入力からは異なるハッシュ値が生成される(衝突の可能性は非常に低い)
- ハッシュ値から元のデータを復元することはできない
ハッシュ関数を使えば、どんなに長いURLでも短い固定長の文字列に変換できます。また、同じURLを2回登録しようとしたときに、同じ短縮コードが生成されるため、重複チェックにも活用できます。
なぜDigest::SHAを使うのか
PerlでハッシュといえばMD5を思い浮かべる方もいるかもしれません。しかし、MD5はセキュリティ上の理由から現在は推奨されていません。
今回使うDigest::SHAは、SHA(Secure Hash Algorithm)というハッシュ関数を提供するモジュールです。SHA-1はMD5より安全性が高く、URLの識別子を生成する用途には十分です。
Digest::SHAはPerl 5.10以降のコアモジュールなので、追加インストール不要で使えます。
Digest::SHAを使ってみよう
モジュールを読み込む
まず、Digest::SHAモジュールを使う準備をします。以下のようにuseで読み込みます。
| |
sha1_hexは、入力データのSHA-1ハッシュ値を16進数の文字列として返す関数です。qwで明示的にインポートしています。
短縮コードを生成する
sha1_hexを使うと、任意の文字列から40文字の16進数ハッシュ値が得られます。ただ、40文字は短縮URLとしては長すぎるので、先頭の6文字だけを使います。
| |
substrは文字列の一部を切り出す組み込み関数です。この例では、sha1_hexで生成した40文字のハッシュ値から先頭6文字を取り出しています。
6文字の16進数は約1677万通り(16^6)の組み合わせがあるため、一般的な個人利用では衝突の心配はほとんどありません。
アプリに組み込んでみよう
コードを追加する
前回作成したapp.plを以下のように修正します。Digest::SHAを読み込み、POSTハンドラで短縮コードを生成するようにしました。
| |
コードの各部分を解説します。
Digest::SHAの読み込み
| |
sha1_hex関数を使うために、Digest::SHAモジュールを読み込みます。
仮のURL保存用ハッシュ
| |
今回は動作確認のため、Perlのハッシュ変数%urlsを使ってメモリ上にURLを保存します。これはサーバーを再起動すると消えてしまうため、次回以降でデータベースに置き換えます。
短縮コードの生成と保存
| |
sha1_hexでハッシュ値を生成し、先頭6文字を短縮コードとして使用します。そのコードをキーにして、元のURLをハッシュ変数に保存しています。
動作確認
morboで起動する
ファイルを保存したら、morboで起動しているサーバーが自動的にリロードされます。もしサーバーを停止していた場合は、再度以下のコマンドを実行してください。
| |
ブラウザで確認する
http://localhost:3000にアクセスします- テキストボックスにURL(例:
https://example.com/very-long-url?param=value)を入力します - 「短縮!」ボタンをクリックします
画面に「短縮コード: a1b2c3」のような6文字のコードと元のURLが表示されれば成功です。
試しに同じURLを再度入力してみてください。ハッシュ関数の特性により、同じURLからは常に同じ短縮コードが生成されることを確認できます。
現状の制限
今回の仮実装には以下の制限があります。
- サーバーを再起動するとデータが消える
- 短縮URLにアクセスしてもリダイレクトされない
これらの課題は、次回以降でデータベースを導入し、動的ルーティングを実装することで解決していきます。
まとめ
今回学んだこと
第4回では、以下のことを学びました。
- ハッシュ関数の仕組みと、URLから一意のコードを生成する方法
use Digest::SHA qw(sha1_hex);でSHA-1ハッシュ関数を使う方法substr(sha1_hex($url), 0, 6)で先頭6文字の短縮コードを生成する方法
次回予告
次回は「忘れないように保存しよう — データベースの準備」をテーマに、SQLiteとDBIを使ってデータを永続化する方法を学びます。サーバーを再起動してもデータが消えない、本格的なURL短縮サービスへの第一歩です。お楽しみに。
