3

免責事項: URL 短縮サービスの作成方法を尋ねているわけではありません ( base-62 でエンコードされた文字列を使用するHEREにある「全単射関数」の回答を既に実装しています)。代わりに、この実装を拡張して、生成された文字列を難読化し、両方になるようにしたいと考えています。

A) 簡単に推測できないシーケンス、および

B) まだ全単射。

base-62 文字セットは簡単にランダム化できますが、問題は、他の基数の他の数値と同じように増加することです。たとえば、考えられる漸進的進行の 1 つは次のようなものです。{aX9fgE, aX9fg3, aX9fgf, aX9fgR, … ,}

要件A)に関しては満足している難読化手法を思いつきましたが、それがB)を満たすかどうかは部分的にしか確信が持てません。アイデアは次のとおりです。

インクリメンタル アプローチで確実に変更されるのは、「1 の位」だけです (実用上の理由から、10 進数の用語を使用します)。前に示した進行例では、それは{E, 3, f, R, …}. したがって、base-62 セットの各文字に固有のオフセット番号 (たとえば、「ゼロ文字」からの距離) がある場合、「1 の位」文字のオフセットを残りの文字列に適用できます。

たとえば、ベース 5 の文字セット{A, f, 9, p, Z, 3}(0 から 5 までの昇順) を想定してみましょう。それぞれに、それぞれ 0 から 5 の一意のオフセットがあります。カウントは次のよう{A, f, 9, p, Z, 3, fA, ff, f9, fp, …}になります。したがって、アルゴリズムは、 の値が与えられると、 andfZ3pを見て、p+3 のオフセットを持ち、文字列を次のように並べ替えますZf9p(基数 5 のセットが循環配列であると仮定します)。次の増分番号は でfZ3ZZのオフセットが +4 の場合、アルゴリズムは を返します39pZこれらの並べ替えられた結果は、実際のbase-62 でエンコードされた文字列を見ることのない「一意の URL」としてユーザーに渡されます。

このアプローチは確かに元に戻せます。最後の文字を見て、負のオフセットで同じ順列を実行します。そして、この理由から、それはまだ全単射でなければならないと考えています。しかし、これが必ずしも正しいかどうかはわかりませんか?私が考慮していないエッジ/コーナーケースはありますか?

編集:私の意図は、パターンのセキュリティよりも短縮URLの長さに重きを置いています。暗号化機能、ブロック暗号などを含む多くのソリューションがあることを認識しています。しかし、私はA)を達成するための最善の方法を尋ねているのではなく、「私のオフセットアプローチはB)を満たすか」ということを強調したいと思います。

あなたが見つけることができる任意の穴をいただければ幸いです。

4

4 に答える 4

2

正直なところ、推測しにくくしたい場合は、単純にしてください。

カウンターモードで実行されている通常の暗号化アルゴリズムから始めます。短縮する URL を取得したら、カウンターをインクリメントして暗号化し、結果を印刷可能な文字 (例: base 64) を使用して変換し、元の URL と短縮バージョンをテーブルに配置して、元の URL を必要に応じて短縮版。

その時点での唯一の問題は、どの暗号化アルゴリズムを使用するかということです。それは、脅威モデルによって異なります。短縮された URL を推測しにくくすることで何が得られるのか正確にはわかりません。そのため、脅威モデルについては少し確信が持てません。

推測を少し難しくしたい場合は、RC4 の 40 ビット バージョンのようなものを使用できます。これは非常に簡単に破ることができますが、ほとんどの人が気にしないようにするのに十分です.

もう少しセキュリティが必要な場合は、DES にステップアップできます。それは壊れていますが、この遅い日付でさえ、それはかなりの作業です.

それ以上のセキュリティが必要な場合は、AES を使用できます。

ただし、セキュリティを強化すると、短縮された URL が長くなることに注意してください。RC4-40 は 5 バイト、DES は 7 バイト、AES は 32 バイトで始まります。印刷可能なテキストにどのように変換するかによって、少なくとも少し拡張されます。

于 2011-06-09T03:25:38.933 に答える
1

私は(phpで)同じ問題を解決しようとしましたが、それらの機能で終わりました:

したがって、A) の場合: アルゴなしで次のレコードを取得するために文字列をインクリメントできないため、(私にとって) 簡単に推測できません。

B) の場合: 私が理解している限り、それは 100% 全単射です。

feistel ネットワークに名前を付けてくれた @Nemo に感謝します。これにより、リンクした最初の関数にたどり着きました。

于 2013-04-06T15:56:02.450 に答える
1

もう 1 つのオプションは、疑似乱数関数から疑似乱数順列を生成する方法であるLuby-Rackoff 構築(こちらも参照) を使用することです。

「ラウンド関数」 F を選択するだけです。F は、キー K と、エンコードするものの半分のサイズのビット ブロックを入力として受け取る必要があります。F は、エンコードするものの半分のサイズのビット ブロックを出力として生成する必要があります。

次に、Luby-Rackoff 構築 (別名「Feistel ネットワーク」) を 4 ラウンド実行し、各ラウンドで異なる K を使用します。

構造は、結果が全単射写像であることを保証し、F が反転しにくい場合、反転することは困難です。

于 2011-06-09T03:47:20.887 に答える
0

人々が URL をクロールするのを避けたいのであれば、URL スペースが密集していないことを確認する必要があるという Nick Johnson の考えは正しいと思います。

簡単なアイデアは次のとおりです。URL を取得し、その先頭にランダムな文字をいくつか追加します。次に、圧縮アルゴリズムを実行します-範囲エンコードを試します(適切なライブラリが見つかった場合は、おそらくベースを指定できます)。これは元の形式に解凍できる必要があり、局所性に影響を与え、エンコードされたスペースをよりまばらにする必要があります。

そうは言っても、ほぼすべての URL 短縮サービスが、サーバー側で状態を含むハッシュ テーブルを保持していると思います。100 文字の URL をロスレスで 5 文字または 6 文字に圧縮するには、他にどのような方法がありますか?

于 2011-06-10T08:11:56.513 に答える