14

数か月前、私は Web アプリケーション用に一意でランダムなコードを実装する任務を負っていました。コードはユーザーフレンドリーでできるだけ小さくする必要がありますが、基本的にランダムである必要があります (ユーザーがシーケンスの次のコードを簡単に予測できないようにするため)。

最終的に、次のような値が生成されました。

Af3nT5Xf2

残念ながら、私は実装に満足することはありませんでした。Guid は問題外でした。ユーザーが入力するには大きすぎて難しかったのです。4 桁または 5 桁の文字/数字の行に沿って何かを期待していましたが、特定の実装では、エンコードした場合、著しくパターン化されたシーケンスが生成されます。 9 文字未満。

最終的に行ったことは次のとおりです。

データベースから一意の連続した 32 ビット ID を取得しました。次に、それを 64 ビット RANDOM 整数の中央ビットに挿入しました。簡単に入力および認識できる文字 (L、l、1、O、0 などの混同しやすい文字をスキップする AZ、az、2-9 など) のルックアップ テーブルを作成しました。最後に、そのルックアップ テーブルを使用して、64 ビット整数を base-54 エンコードしました。上位ビットはランダムで、下位ビットはランダムでしたが、中央のビットは連続していました。

最終結果は、GUID よりもはるかに小さく、ランダムに見えるコードでしたが、まったくそうではありませんでした。

この特定の実装に満足したことはありません。あなたたちはどうしたでしょう?

4

6 に答える 6

8

これが私がそれを行う方法です。

一般的な英単語のリストと、使用頻度と文法情報 (名詞なのか動詞なのかなど) を取得します。いくつかのコピーについては、インターチューブを見渡すことができると思います。Firefox はオープンソースであり、スペルチェッカーを備えているため、何らかの方法で入手できるはずです。

次に、あいまいな単語が削除され、長すぎる単語が除外されるように、フィルターを実行します。

次に、私の生成アルゴリズムは、リストから 2 つの単語を選択して連結し、ランダムな 3 桁の数字を追加します。

次のような動詞/名詞間の単語選択パターンをランダム化することもできます

eatCake778
pickBasket524
rideFlyer113 など。

ケースはキャメルケースである必要はありません。ランダム化することもできます。数字と動詞/名詞の配置をランダムにすることもできます。

そして、それは多くの無作為化であるため、Jeff のThe Danger of Naivetéは必読です。また、事前に辞書攻撃についてよく調べておいてください。

実装後、テストを実行して、アルゴリズムが衝突しないことを確認しました。衝突率が高い場合は、パラメーターをいじります (使用される名詞の量、使用される動詞の量、乱数の長さ、単語の総数、さまざまな種類のケーシングなど)。

于 2008-08-29T16:58:12.253 に答える
3

C# では、' System.IO.Path.GetRandomFileName() : String ' メソッドを使用しましたが、デバッグ ファイル名のソルトを生成していました。このメソッドは、ランダムな「.xyz」ファイル拡張子を除いて、最初の例のように見えるものを返します。

.NET を使用していて、より単純な (ただし「見栄えがよくない」) ソリューションが必要な場合は、これで十分だと思います...必要に応じて、ランダムなファイル拡張子を削除できます。

于 2008-08-29T16:53:34.950 に答える
3

.NET では、RNGCryptoServiceProvider メソッド GetBytes() を使用できます。これは、「バイト配列を暗号的に強力なランダム値のシーケンスで埋めます」(ms ドキュメントより)。

byte[] randomBytes = new byte[4];
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetBytes(randomBytes);

バイト配列の長さを増やして、許可したい文字値を抜き出すことができます。

于 2008-08-29T16:56:29.450 に答える
0

ユーザーフレンドリーとは、ユーザーが回答を入力できることを意味する場合、別の方向を見たいと思うでしょう。私は、ランダムな単語と数字をより簡単でエラーが発生しにくい文字列として選択する初期ランダム パスワードの実装を見て、実行しました。

URL 文字列にランダム コードをエンコードする方法を探しているのですが、これは私がしばらく扱ってきた問題ですが、私が行ったことは 64 ビットでエンコードされた GUID を使用することです。

于 2008-08-29T17:07:09.050 に答える
0

chakrit が提案した単語のリストを、一意のシーケンシャル キーを使用してデータ テーブルまたは xml ファイルに読み込むことができます。ランダムな単語を取得するときは、乱数ジェネレーターを使用して、キーによって取得する単語を決定します。それらのうちの 2 つを連結する場合、「真のランダム性」が目標の一部でない限り、文字列に数字を含める必要はないと思います。

于 2008-08-29T18:20:03.853 に答える