8

次の文字から 6 桁のコードを生成しています。これらはステッカーにスタンプするために使用されます。
それらは (印刷前に) 10k 以下のバッチで生成され、合計で 100 万から 200 万を超えることはないと思います (おそらくはるかに少ない)。
コードのバッチを生成したら、既存のコードの MySQL データベースをチェックして、重複がないことを確認します。

// exclude problem chars: B8G6I1l0OQDS5Z2

$characters = 'ACEFHJKMNPRTUVWXY4937';

$string = '';

for ($i = 0; $i < 6; $i++) {
    $string .= $characters[rand(0, strlen($characters) - 1)];
}   

return $string;
  1. これはコードを生成するための確実なアプローチですか?
  2. 可能性のある順列はいくつありますか? (21 文字のプールからの 6 桁のコード)。申し訳ありませんが、数学は私の得意分野ではありません
4

6 に答える 6

14

21^6 = 85766121 の可能性。

DBを使用して使用済みの値を保存するのは悪いことです。ランダム性を偽造したい場合は、次を使用できます。

可能な数を 19 に減らし、p が奇素数である次数 p^k のグループは常に循環的であるという事実を利用します。

次数 7^19 のグループを取り、7^19 への相互素数ジェネレータを使用します (ここでは 13^11 を選択します。7 で割り切れないものを選択できます)。

次に、次のように動作します。

$previous = 0;

function generator($previous)
{

  $generator = pow(13,11);
  $modulus = pow(7,19); //int might be too small
  $possibleChars = "ACEFHJKMNPRTUVWXY49";

  $previous = ($previous + $generator) % $modulus;
  $output='';
  $temp = $previous;

  for($i = 0; $i < 6; $i++) {
    $output += $possibleChars[$temp % 19];
    $temp = $temp / 19;
  }

  return $output;
}

すべての可能な値を循環し、掘らない限り少しランダムに見えます。さらに安全な代替手段は乗法群ですが、私はすでに数学を忘れています:(

于 2013-05-09T23:36:41.857 に答える
3

21 ^ 6 コード = 85 766 121 ~ 85.8百万コードになります。

それらをすべて生成するには (時間がかかります)、この質問に対する選択された回答を見てください:数字または単語を取り、可能なすべての組み合わせを見つけるアルゴリズム.

于 2013-05-09T23:36:05.973 に答える
3

ババが言ったように、その場で文字列を生成すると、大量の衝突が発生します。すでに生成されている 8000 万に近づくほど、利用可能な文字列を取得するのが難しくなります

別の解決策は、可能なすべての組み合わせを一度生成し、それらのそれぞれをデータベースに既に格納し、行/トークンが既に使用されているかどうかを示すブール列フィールドを使用することです。

次に、それらの1つを取得します

SELECT * FROM tokens WHERE tokenIsUsed = 0 ORDER BY RAND() LIMIT 0,1

そして、それをすでに使用済みとしてマークします

UPDATE tokens SET tokenIsUsed = 1 WHERE token = ...
于 2013-05-10T00:10:07.143 に答える
0

私は同じ問題を抱えていましたが、非常に印象的なオープンソースのソリューションを見つけました。

http://www.hashids.org/php/

取得して使用することができます。また、内部で何が起こっているかを理解するためにソース コードを調べることも価値があります。

于 2013-06-15T22:54:51.880 に答える
-2

または... md5でユーザー名+日時をエンコードしてデータベースに保存できます。これにより、一意のコードが生成されます;)

于 2015-06-01T07:44:58.480 に答える