2009-04-15 8 views
5

私は、ユニークで非シーケンシャルなIDを生成する必要のあるアプリケーションに取り組んでいます。私が持っている制約の1つは、3桁の数字とそれに続く2文字(約600k IDのみ)で構成されなければならないということです。私の比較的小さなIDのプールを考えると、私は単純にすべてのIDを生成し、それらをシャッフルしてデータベースに入れることを検討していました。内部的には、シンプルでシーケンシャルなIDを使用するので、一度に1つずつ抜き出すのは簡単です&私はリピートがないことを確認してください。数字のシーケンスをランダムなIDに変換しますか?

これは非常に満足できる解決策ではありません。そこにいる誰かが、この「宝くじ」方法よりも限定されたプールからユニークなIDを生成するもっと面白い方法を持っていますか?それは次のようになりますので

+0

実際に使用するIDの数はいくつですか?非常に多くを生成し、それらを例えば数百だけ使用するために保管することは残念です。 –

+0

連続しているのはなぜ重要ですか? – ninesided

答えて

4

これは、最適化しようとしているもの(速度、メモリ使用率など)に応じてさまざまな方法で行うことができます。

IDパターン= DDD C 1 C [0]

オプション1(本質的にザックのと同様ハッシング、等):
1 0及び可能性(676k)の数の間の乱数を生成します。 IDとインクリメントが存在する組み合わせ

ddd = random/(26^2) 
    c[0] = random % (26) 
    c[1] = (random/26) % 26 

3-クエリDBに
2-変換番号フリーつが見つかるまで。

オプション2(線形フィードバックシフトレジスタ、wikipediaを参照):範囲内の乱数(0,676k)と
1-種子。(すなわち0xA50A0 +)範囲よりもIDが大きくスキップ

num = (num >> 1)^(-(num & 1u) & 0x90000u);

3-現在のID番号に以下を適用することによって、後続の乱数を生成
2-(あなたは「0」で播種することができない理由を下記参照)
-番号をID形式に変換する(前述のように)
* IDに使用された最後の番号を保存する必要がありますが、DBを照会する必要はありません。この解決策は、LFSRの働きにより、[000 AA]を除くすべてのIDを列挙します。

[編集]あなたの範囲はあなたが必要とするよりも実際に大きいので、あなたがIDに変換する前に1を減算することにより、バック[000 AA]を取得し、有効範囲はなることができます(0,0xA50A0]

+0

私は好奇心が強いです。そのLFSRアルゴリズムはどこから来たのですか? –

1

あなたにシーケンシャル定義内容に応じて、あなただけの、そのような3桁の数字による「AA」、そしてちょうどループとして、文字の上にある特定の出発点を選ぶことができます: 001aa 002aa 003aa

zzになったら、数字の部分を増やしてください。

4

この規格に準拠したランダムなIDを生成し、既に存在するかどうかを確認するためにDBを選択し、DBに挿入して使用済みであることに注意してください。そのスキームの寿命の最初の25%(または約150,000エントリ)の間、新しいランダムIDを生成するのは比較的速いはずです。その後、それはもっと長くかかりますが、あなたは無料のIDを探すためにテーブルをあらかじめ充填しておくこともできます。

+0

これは、未使用のIDを返したストアドプロシージャでこれをカプセル化できます。あなたが実際にIDの – ninesided

4

有限群を使用します。基本的には、32または64ビットの整数をとり、整数の最大値に比例する大きな数を見つけます。この数Mと呼ぶ。そして、すべての整数nについて、n * Mは桁数の多い固有の数となる。

これは、データベースをあらかじめ入力する必要はなく、別の選択クエリを実行する必要がないという利点があります。を自動インクリメント別のID列がデフォルトのn * Mになるようにしてください。

+0

をテストするときにデータベースを繰り返しハンマーしていないような方法で、これらのIDの2つが並んでいれば(あるいは本当に任意の距離で3つ以上ある場合)、IDのgcdを取ることができます次のIDを正確に予測することができます。残念なことに、この解決方法はエントロピーが非常に少ないでしょう。また、これはOPが使用した3桁の2文字仕様には適合しません – Zak

0

ますIDを生成するために、モジュラー算術演算を使用することができます676000とし、種子のための互いに素である数を選びidは、テーブルの標準インクリメントIDですその後、次の擬似コードは、何が必要です:。。。

uidNo = (id * seed) % 676000 
digits = uidNo/676 
char1 = uidNo % 26 
char2 = (uidNo/26) % 26 
uidCode = str(digits) + chr(char1+65) + chr(char2+65) 

ユーザーならば複数のIDが連続して発行されている場合、アルゴリズムとシードを推測してすべてのIDを順番に生成できます。アルゴリズムがあなたのユースケースに対して十分に安全でないことを意味します。

関連する問題