長い URL を入力フィールドに入力すると、その URL が「http://www.example.org/abcdef
」に短縮される URL 短縮サービスを作成したいと考えています。
「 」の代わりに、abcdef
を含む 6 文字の文字列を使用できますa-z, A-Z and 0-9
。つまり、560 億~ 570 億の文字列が考えられます。
私のアプローチ:
3 つの列を持つデータベース テーブルがあります。
- ID、整数、自動増分
- long、文字列、ユーザーが入力した長い URL
- short、文字列、短縮 URL(または 6 文字のみ)
次に、長い URL をテーブルに挿入します。次に、「 」の自動増分値を選択しid
、そのハッシュを作成します。このハッシュは「short
」として挿入されます。しかし、どのようなハッシュを作成すればよいでしょうか。MD5 などのハッシュ アルゴリズムでは、長すぎる文字列が作成されます。私はこれらのアルゴリズムは使用しないと思います。自分で作成したアルゴリズムでも機能します。
私のアイデア:
「http://www.google.de/
」については、自動増分 ID を取得します239472
。次に、次の手順を実行します。
short = '';
if divisible by 2, add "a"+the result to short
if divisible by 3, add "b"+the result to short
... until I have divisors for a-z and A-Z.
数が割り切れなくなるまでこれを繰り返すことができます。これは良いアプローチだと思いますか? もっと良いアイデアはありますか?
このトピックへの継続的な関心により、私はGitHubに効率的なソリューションを公開、実装ありJavaScript、PHP の、パイソンそしてジャワよろしければ解決策を追加してください:)
ベストアンサー1
私は「数値を文字列に変換する」アプローチを継続します。ただし、ID が素数で 52 より大きい場合、提案されたアルゴリズムは失敗することがわかります。
理論的背景
あなたには必要だ全単射関数 f 。これは、 f(123) = 'abc'関数の逆関数g('abc') = 123を見つけるために必要です。これは次のことを意味します。
- f(x1) = f(x2)となるようなx1, x2(x1 ≠ x2)は存在しない。
- そして、あらゆるyに対して、 f(x) = yとなるxを見つけることができなければなりません。
IDを短縮URLに変換する方法
- 使用したいアルファベットを考えてみましょう。あなたの場合は です
[a-zA-Z0-9]
。62文字が含まれています。 自動生成された一意の数値キー (
id
たとえば、MySQL テーブルの自動増分) を取得します。この例では、125 10 (125 の底が 10)を使用します。
ここで、125 10 をX 62 (基数 62)に変換する必要があります。
125 10 = 2×62 1 + 1×62 0 =
[2,1]
これには整数除算と剰余の使用が必要です。疑似コードの例:
digits = [] while num > 0 remainder = modulo(num, 62) digits.push(remainder) num = divide(num, 62) digits = digits.reverse
次に、インデックス 2 と 1 をアルファベットにマッピングします。マッピング (たとえば配列を使用) は次のようになります。
0 → a 1 → b ... 25 → z ... 52 → 0 61 → 9
2 → c、1 → b とすると、短縮 URL としてcb 62 が表示されます。
http://shor.ty/cb
短縮URLを初期IDに解決する方法
逆の場合はさらに簡単です。アルファベットで逆引きするだけです。
e9a 62 は「アルファベットの 4 番目、61 番目、および 0 番目の文字」に解決されます。
e9a 62 =
[4,61,0]
= 4×62 2 + 61×62 1 + 0×62 0 = 19158 10次に、データベース レコードを見つけて
WHERE id = 19158
リダイレクトを実行します。