2009-07-02 3 views
16

私は、競技会で使用される約6300万の固有コードを生成する「スマートで」安全な方法を考え出しています。コードは約10文字です。6,300万の賞金コードの生成方法

誰もこの問題から生じる可能性のある「ハードル」を似たように認識していますか?誰かがコードを推測できる確率を最小限に抑えるにはどうすればよいですか?

このプロジェクトはPHPで行われますが、それは問題ではありません。ここで問題となるのはもっと論理です。

フィードバックは本当にありがとうございます。

UPDATE ちょうどそれが10 文字、大文字小文字を区別しないアルファ数値のになります明確にします。 A-Z0-9

答えて

30

構文

あなたはおそらく、これらのコードをコピーする人々を持っていますので、それは、これらのコードをコピーして簡単にする必要がありますを意味します。 Gamecatが指摘するように、10^10は小さすぎます。しかし、それはもう一つの問題を引き起こします。「1」は「私」のように見えます。 "0"、 "C"、 "O"、 "Q"も非常に似ています。これは大きな問題ではありません。安全なアルファベットを定義してください: "ABDEFGHJKLMNPRSTUVXYZ"(COIQは除外)コメントから:あなたが選んだフォントによっては、5/SとU/Vも視覚的に曖昧です。必要に応じて交換してください。これは32シンボル(5ビット)のコードです。 10文字のコードは50ビットの数字です。推測される確率は約0.63E-7です。

コードは覚えがたいので、コピーするときに休憩ポイントが必要です。したがって、2つまたは3つの部分で文字列を分割し、入力フィールドがこの内訳と一致することを確認します。

など。 AKG3L-45TEE => 5つのグループが2つあり、5文字を覚えていなくても、読んでいた箇所を見つけるのがずっと簡単です。彼らにを生成する方法


は:

これはかなり簡単です。候補を生成するのに特に洗練されたアルゴリズムは必要ありません。必要なコードあたり10個の乱数を生成し、各数字から5ビットを取ることができます()。中位のビットが最もよく、たとえば(rand()/ 64)モジュロ32)です。この値[0-31]をアルファベットのインデックスとして使用します。この文字列を主キーとしてデータベーステーブルを作成し、テーブルに6,300万エントリが入るまで挿入します。おそらく、 "生成された"日付と "償還された"日付をこのテーブルに追加することをお勧めします。

+8

+1混乱している値を取り除く良い点 –

+0

そして32個のシンボルを持つことでいくつかのことを単純化することもできます –

+4

文字ess 'S'と数字5 '5'も同型です。 – dwhall

0

安全な乱数ジェネレータを使用してください。

+1

推測の確率:63 * 10^6/10^10 = 1/159 – kgiannakakis

+1

私はこれに少しでも援助していますが、これはちょっと役に立たないと思います。 –

+0

私は誰もキャラクター数字でなければなりません。 [0-9a-z]は63 * 10^6/36^10 = 17/1000000000となります。 [0-9a-Z]は63 * 10^6/62^10 = 75/1000000000000となります。 –

0

ユニークな参加者の場合、各参加者の名前(および/または)をハッシュして最初の10文字まで切り捨てることができます。

+1

ハッシュは、技術的には必ずしもユニークではないかもしれません。 – Sampson

+0

コードは製品に配布され、請求されるので、値を作成する参加者との接続はありません。 –

+0

@ Shadi - oh。私の謝罪。 @Jonathan - 確かに、私は、入力ストリングを十分に長くするためにハッシュを作成するために詳細を追加するように頼んだのです。私は63mでどれだけ高い確率で衝突する可能性があるのか​​分かりません。 まだ他の答えがはるかに良いです。私はUUIDも知らなかった。 :) – OrangeRind

0

多分これはあなたに少しを助ける:Universal Unique Identifier

のUUIDの意図は一意 重要な中央の調整なしの情報を識別するために 分散システムを有効にすることです。 したがって、誰でもUUIDを作成して、 という識別子を という識別子が決して となることはないと確信して、何かを識別するためにそれを使用することができます。 他の人。

+1

最後の 'r'を追加するのを忘れた :) – OrangeRind

+1

UUID v4では、これはエントロピーの無駄にすぎません。ほとんどのデータを捨ててしまいます。他のUUIDバージョンでは、データはあまりランダムではないかもしれません(NICのMACアドレスとシステム時間またはそれらのハッシュは本当に良いランダムデータソースではありません)。 – drdaeman

+0

Upsありがとう...気をつけてコピー&ペースト;)うん、私はそれが実際にかなりの乱数を生成するのはかなり難しいことを知っています。その膨大な量の実際にランダムなデータには、物理​​的な実験(放射性崩壊)から自然にランダム(少なくとも機械発電機以上のもの)であると思われる測定データを得ることが最もよいでしょう。 – Daff

2

PHPで英数字文字列を生成する場合はlinkを参照してください。それは36文字のアルファベットを使用します。これは十分に安全でなければなりません。ただし、一意性は保証されていません。私はこれを実装するためにSetを使うことができると思います。これは1回限りの操作なので、重複をテストするための時間遅延は大きな問題ではありません。

+0

はい、そうです。データが設定されているので、DBに配置するときにコードが存在するかどうかをチェックするのは難しくありません。 –

+1

6400万のコードを生成し、ソートし、重複をチェックする方が高速です。 O(N log N)のみ。 – MSalters

+0

@MSlaters:重複チェックはどのように行いますか? –

5

0 - 2 -1の範囲の真にランダムで一意な64ビット数の集合を生成します。見たものを追跡し、重複を拒否する必要があります。この数字の下位50ビットの各5ビットを32文字のアルファベットから引く - 基本的に英語のアルファベット(大文字または小文字)のすべての文字からLとOプラス2〜9の数字を引いたもの(これはl/1および0/O)。 6300万のコードの場合、有効なコードシーケンスをランダムに選択する確率は0.000006%(63,000,000/2 )になります。

私はこれも自動生成されたプライマリキー(int)を使って行い、32ビットのランダム値でビットインターリーブしました。この例では、完全な64ビットを使用してアルファベットから13文字を生成し、15文字コードの固定位置に2つのランダムな文字を追加しました。コードを使用する際には、アルゴリズムを逆にしてキーとランダム性を抽出し、2つの余分なランダムな文字をスローし、ランダム性をキーに格納されているものと比較してコードを検証します。

10

私が正しく理解している場合、 "推測因子"が低い10桁の63万のコードを作成したいと考えています。

有効な組み合わせは10,000,000,000件あります。これらのうち63,000,000が価格です。 63/10,000 = 0.0063。したがって、それぞれの推測には成功の確率は0.63%です。高いとは言えませんが、無理な力で、数値は非常に簡単です。

63万倍の比率で十分ですか?

+2

これは良い点です。 –

+2

10進数字を使用しない理由があります。 kgiannakakisを参照してください – MSalters

+0

彼は具体的に文字ではなく、数字を言った。良い警告だが、彼はすでにそれを得ていると思う。 – tvanfosson

0

コードの長さは10 '文字ですが、文字セットは何ですか?

ちょうど数字の場合、(@Gamecat)それはおそらくランダムに推測するのが簡単すぎるでしょう。

一方、文字セットが文字+数字である場合は、十分な安全性があります。

いずれの場合も、安全な乱数ジェネレータを使用して生成し、データベースに入れる前に重複をチェックします。

4

誤って混乱したり恥ずかしいことを起こしたくないので、コードに英数字を使用するときは注意してください。混乱を避けるために、1とL、0とO、そしておそらく8とBを削除することをお勧めします。恥ずかしさを避けるために、すべての母音を削除して、間違って何かを綴ることはできないようにしてください。