重複のない10桁の数字をIDとして採番するアルゴリズムを教えて下さい。


但し、下記の条件があります。

- 最低でも1億以上、採番可能なもの
- 時系列や連番など推測されやすいものはNG
- 基本的にデータベースを使用せずアルゴリズム内だけて採番(但しカウントアップ用で使うならOK)
- 数字が一意であると保証されていること

以上になります。

PHPのコードで書かれてると、なお有り難いです、
宜しくお願いします。

回答の条件
  • 1人5回まで
  • 13歳以上
  • 登録:2013/08/26 07:16:11
  • 終了:--

回答(3件)

id:taknt No.1

きゃづみぃ回答回数13010ベストアンサー獲得回数11212013/08/26 07:41:27

まず1億分の配列に連番で取得させます。

その後、配列をランダムにします。

あとは採番のときに 順に配列から値を取得すればいいです。

id:taknt

上記の配列にセットするのは プログラムに固定で持たせれば よいでしょう。

2013/08/26 09:29:21
id:holoholobird No.2

holoholobird回答回数471ベストアンサー獲得回数842013/08/26 09:41:51

idの重複を確実になくすならこれしか方法はないと思います。

<?php
$p=100;
$temp=range(1,$p);
shuffle($temp);
print_r($temp);
?>

たとえば上の例だと$p=100なので、$tempは1~100までの数字を重複なしにランダムに格納した、100の要素の配列になります。

$pの数字は適当にかえてください。

http://codepad.org/KfMrQ2u2
↑こういう結果になります。

id:dawakaki No.3

だわかき回答回数716ベストアンサー獲得回数1102013/08/26 19:26:00

No.2の回答では連番生成されるので、簡単にIDが推測されてしまいます。
推測がしにくいユニークIDを発生させる方法としては、uniqid関数とmd5関数の組み合わせが考えられます。

以下のスクリプトは、ユニークIDを10進数10桁に変換し、配列$arrの添え字として1億個を発生させるものです。

$arr = array();
while (count($arr) <= 100000000) {
    $id = md5(uniqid(rand(),1));
    $id = substr(hexdex($id), 0, 10);

    $arr[$id] = TRUE;
}
  • id:Lhankor_Mhy
    回答No.1とNo.2は「基本的にデータベースを使用せず」って書いてあるの読んでから回答した方がいいと思うんだが。その1億件のIDをDBに入れずにどうするつもりでその回答なんだ?
  • id:standard_one
    M系列の疑似乱数なら同じ値の繰り返しになるので、適当なシード値とXORマスクを用意して
    乱数生成 → 1億未満または11桁以上なら乱数生成に戻る → 乱数取出し → 生成した乱数をシードにして先頭に戻る
    で目的達成ですね。
    10進数で10桁必要なら34ビットで乱数生成すればいいです。
    コード書こうかと思ったんですがダルいので他の人に譲ります。ということで回答ではなくコメントにしておきます。
    なぜこれで数字が一意であると保証されるかは…ビット演算の説明から入らないといけないので自習してみてください。
    当然一周したら(100億以上の値を出力したら)同じ値が出ます。
  • id:Lhankor_Mhy
    ↑横ですが勉強になりました。ありがとうございます。
    実装には「乱数生成→出力→シード保存」の間は排他処理しないといけないと思うので、質問者はその辺を気をつけたほうがいいでしょうね。
  • id:Lhankor_Mhy
    回答No.3もさあ……、なんで指摘済みのこと繰り返すかな。
     
    その要素数1億の配列をどうするつもりなんだってば。シリアライズしてテキストファイルにでも保存しておくの?
    つーかそもそも、「連番生成される」って指摘してるけどshuffle関数で破壊的に配列の順番を入れ替えてるじゃん。
     
    IT漫才という新ジャンルを見てる気分になってきたよw

トラックバック

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません