1 :
初心者:
Cの標準ライブラリのrand()では、seedが同じなら
発生する乱数系列も同じになってしまいますよね?
完全な(?)乱数を発生させるにはどうしたらいいんでしょうか?
time()と%演算子を利用するしか思い付きません。
2 :
デフォルトの名無しさん:2001/01/08(月) 18:28
>完全な(?)乱数を発生させるにはどうしたらいいんでしょうか?
無理です。
go to 初心者板
早いレスありがとうございます。
了解しました。
>2,3
5 :
名無しさん:2001/01/08(月) 19:30
ハード的に実現してるのがありますよね。
熱雑音拾ってそれを種にしてるの
6 :
デフォルトの名無しさん:2001/01/08(月) 19:44
Win32なら::GetProcessTimes()の結果を
めるせんぬついすたーに仕込む.
7 :
ボログラマー:2001/01/08(月) 19:45
時間を種にするんだよ。
unsigned long seed;
time_t t;
time(&t);
seed = t;
んで、あとは
unsigned long rnd()
{
return seed *= 69069;
}
とかすれば良し。
69069という値には意味があるので、適当な値ではダメ。
8 :
デフォルトの名無しさん:2001/01/08(月) 19:45
あと::GetTickCount()も追加しておこう.
9 :
デフォルトの名無しさん:2001/01/08(月) 19:50
time()は1も考え付いてるよーで。
10 :
6=8:2001/01/08(月) 20:01
time()だと同時に複数走らせたらかぶるじゃん.
ムカーシ読んだ技術書で
放射線源とガイガーカウンタ組み合わせた
乱数発生器の解説を読んだ気がするんだけど、、、
ルディーラッカーとかのSF小説と混同してるかもしれない
昔の三国志みたくHit space key.
13 :
名無しさんi486:2001/01/08(月) 22:33
Pen4とかには乱数発生器が付いてるそうだけど
これは使われてるの?
>7
seedが偶数なら常に偶数(奇数も同様)にしかならないが、
そういうのも乱数と呼ぶのか?
15 :
デフォルトの名無しさん:2001/01/09(火) 00:09
時刻とか熱雑音使っちゃうと、乱数の再現性がなくなっちゃうよね。
>15
乱数の再現性ってなんじゃい?
アホ発見>16
>>11 ”ソフトウエア”ですな。♪ビーバッパルーラ〜
ゲームなんかのときはシードも保存してるけど
Rレジスタの値をつかえ
int c1, c2;
int a, b;
c1 = GetTickCount();
a = 0;
for( b=0; b<100000; b++){
a += 400;
a /= 3;
/* ていうか,このあたりは適当に... */
}
c2 = GetTickCount();
printf("%d\n", c2-c1 );
これ,わりと値がバラけるんですよね。
私の環境(Pentium200MHz)では 27〜111 くらいでバラバラに。
・・やっぱし邪道っす?
ファイアーエムブレム(聖戦の系譜以降)なんかは擬似乱数の性質を逆に利用して
リセットして同じことを繰り返しても結果はおなじなんてシステムにしてた。
>10
プロセスID(のたぐい)を足すべし。
24 :
ボログラマー:2001/01/09(火) 18:11
>>10 staticで使え。まぁ、同じタイミングで2アプリ起動されたらアウトだけどネ。
そのへんはユーザーの入力使ったり。<この辺がボロっぷり暴露してんな、俺。
>>23 ナイス。そうしてplz。
>>14 まぁ0〜((2^32)-1)の値が欲しい場合はまずいだろうが、
通常は定数で割って上部のビットを使用するから、問題ナシ。
25 :
10:2001/01/09(火) 21:10
>>24 自分は擬似乱数サーバクラスをSingletonで作って
コンストラクタでGetTickCount(), Time()で初期化するってのを
やってるよ.
おっしゃるとおりスレッドハンドル辺りを足すぐらいでいい鴨.
↑がいしゅつだし、原典のほうを書こうよ。
でもGCAはお世話になってます。
乱数について:7
29 :
デフォルトの名無しさん:2001/03/18(日) 04:45
623次元に均等だとかはどうでもいいのですが、再現性や規則性のない
seedを作る方法が知りたいです、、、age
30 :
デフォルトの名無しさん:2001/03/18(日) 04:49
>>29 完全な乱数なんてないよ。
周期が長いのとか、いろいろのってるので、アルゴリズム辞典を見たら?
31 :
デフォルトの名無しさん:2001/03/18(日) 05:05
周期がいくら長くても、種から結果が推測できては、パスワード生成など
には使えないですよね。
time() だと同じ秒で実行すると同じ結果になるし、getpid() でも所詮
何万種類のパターンしかできません。
熱雑音とかマニアックな方法じゃなくて、もっと手軽で実用的な乱数生成
の仕方はないのでしょうか。
32 :
デフォルトの名無しさん:2001/03/18(日) 05:12
今のところ思い付くのは、パケットの送受信にかかる時間とか、
WWWサーバのログの大きさとかなんですけど。
33 :
デフォルトの名無しさん:2001/03/18(日) 05:12
>>31 あの〜、再現性がないと暗号を復元できないと思うんですが。
大丈夫ですか?
アルゴリズム辞典のやり方でも2の54乗通りのパターンができるやつ
が載っているので、そっち応用してください。
34 :
デフォルトの名無しさん:2001/03/18(日) 05:25
暗号の話ではなくて、単に推測しづらいパスワードを作りたいだけなんです(泣
生成したパスワードはどっかに保存しておく所存です。
35 :
デフォルトの名無しさん:2001/03/18(日) 05:40
ユーザの入力を種にすれば、UNIXの crypt とかでもよいのでしょうが、
ユーザの入力に頼らずに種を作りたいのです。
36 :
デフォルトの名無しさん:2001/03/18(日) 05:41
>>32 統計的に大きく偏ると思われ。
数学的に解決した方が良いかと。
>>35 マウスカーソルの位置も取得して計算するとか
時間+pid+位置+・・・すべて一致するのはあまりないとおもう
38 :
デフォルトの名無しさん:2001/03/18(日) 09:17
WindowsならCoCreateGuid をタネにしたら
39 :
麻衣:2001/03/18(日) 10:49
じゃ これでどう?
#include<stdio.h>
#include<windows.h>
static WORD randbuf[16]; // 256bit
WORD rand16(void)
{ // p=55 τ=127-7=120
static WORD rw=7;
WORD topb =randbuf[rw ];
WORD nw=(rw+8-1) & 7;
WORD nextb =randbuf[nw ];
topb = (topb<<8)|( nextb>>(16-8) );
topb^=nextb;
randbuf[rw]= topb ;
rw = nw;
return topb^ randbuf[rw+8];
}
void rand32Init(void) { CoCreateGuid((GUID *)randbuf);}
int charc(WORD c)
{ WORD a='Z'-'A'+1;
c %= a+10;
if(c>=a) return '0'+c-a;
return 'A'+c;
}
int main()
{
int i;
rand32Init();
for(i=0;i<100;i++) rand16();//シャッフルする
for(i=0;i<16;i++)
printf("%c",charc(rand16() )) ;
printf("\n");
return;
}
40 :
麻衣:2001/03/18(日) 11:01
あれ?
topb = (topb<<8)|( nextb>>(16-8) );
は
topb = (topb<<(15))|( nextb>>(16-1) );
かな? まあいいや、無理にM系列にするより
何かワラらない系列の方が解析しにくいかもね
41 :
デフォルトの名無しさん:2001/03/19(月) 12:11
>>38-40
ありがとうございます。
厚かましいようですが、UNIX上でやる方法も知りたいです。
作成したプログラムのソースを配布すると、パスワードを生成するアルゴリズム
は周知になると思いますが、それに基づいて生成されたパスワードは予測できない
ようにしたいのです。
42 :
麻衣:2001/03/19(月) 22:13
麻衣はウニックスの事は知らないもん
でも、ようは WORD は 符号無し16bitで定義する事と
rand32initで 256bit分出鱈目な値で埋めるればOK
時計の他に、NICのアドレスとか、CPUのカウンタとかIDとか
思いつくもの全部使えばいい。
最初100回ループしてる個所を固定回数じゃなくて 別の適当な
プロセスを走らせてそのプロセスが帰ってくる迄とか適当にばらつ
くような回数に変更すれば完璧かな
43 :
トーシロ:2001/03/20(火) 21:35
>>41 DESとかビット列がばらけるので予測が困難だと聞きましたが、違うのでしょうか?
そんなに予測不可能にしたいというなら、
DESの三重使用とか、複数の暗号を組み合わせて使うというのではまずいのでしょうか。
※素人考えですいません。
44 :
デフォルトの名無しさん:2001/03/20(火) 21:39
言いたい事は、
時計とか本人の名前とかを 暗号化すりゃいいんじゃないの?
という事かい?
そりゃそうだ
45 :
44:2001/03/20(火) 23:00
そりゃそうだけど、この場合復号しなくていいから
より問題は単純だ
46 :
デフォルトの名無しさん:2001/03/21(水) 00:32
{0,1,2,3,4,5,6,7,8,9}も、
{1,1,1,1,1,1,1,1,1,1}も、
「これは乱数だ」と言い張れば乱数です。
47 :
名無しさん:2001/03/21(水) 02:43
CPUはたまに計算を間違える事があるから
それを利用するってのはどうだろう
まずCPUを熱暴走ギリギリにして・・・
48 :
名無しさん:2001/03/21(水) 03:02
unixでなら /dev/random を乱数発生器として使えるものが
あるようです。全部で使えるとは思わないけど
49 :
デフォルトの名無しさん:2001/03/21(水) 07:01
1、適当にpingを送って 応答が帰って来るまでの時間
2、ウエーブデバイスがあれば 16bit精度で入力してみる
マルチメディアタイマは水晶が別なので、CPU側で時間を計る
3、アナログジョイステックデバイスがあれば 現在のCRの値
4、別のプロセスでファイルの入出力(HD/FDに)をさせ
て、その処理にかかる時間を測定する
を全部試して非常に大きなタネを作ればいい
50 :
デフォルトの名無しさん:2001/03/21(水) 10:48
ランダムな外部入力(キー入力、マウスクリックなど)
をいろいろ集めてmd5でハッシュして作り出せ
ってゆーか、gnupgやopensslや
unixの/dev/randomのソース見ろヴぉけ
51 :
デフォルトの名無しさん:2001/03/21(水) 11:01
53 :
41:2001/03/21(水) 20:03
ありがとうございます > all
/dev/urandom ってのをつかってできました。(Linux)
/* #include は省略 */
#define MY_RAND_BYTES 3
#define MY_RAND_MAX 256 * 256 * 256
int myrand(int max){
int fd, val, i;
unsigned char c;
assert(max > 0 && max <= MY_RAND_MAX);
if((fd = open("/dev/urandom", O_RDONLY)) == -1) return -1;
val = 0;
for(i = 0; i < MY_RAND_BYTES; i++){
if(read(fd, &c, 1) != 1) return -1;
val = val * 256 + c;
}
close(fd);
return val % max;
}
54 :
41:2001/03/21(水) 20:10
あ、
return val % max;
でなくて、
return val % max + 1;
の方がよい気がします。
55 :
デフォルトの名無しさん:2001/03/22(木) 02:14
>>53 /dev/urandomは、速いけど、乱数の精度があまり高くない時もある
暗号に使う場合は/dev/randomつかってね
げーむくらいならどっちでもいいけど
56 :
デフォルトの名無しさん:2001/03/22(木) 03:12
しかし、/dev/random の方は「エントロピープール」とやらが無くなると(すぐ無くなるけど)、
read がブロックする問題が、、、。
もちろん、真の乱数を種にして後は疑似乱数を使うことで乱数発生器の利用回数を減らすこと
はできますけど、ブロックする可能性は消せませんよね。
59 :
デフォルトの名無しさん:2001/03/27(火) 12:53
/dev/random がない場合はどうすればいいの?
60 :
デフォルトの名無しさん:2001/03/29(木) 03:18
真の乱数といっても32ビットや128ビットじゃないんですか?
有限状態オートマトンであるコンピュータに数学的な真の乱数なんて無理だろ
やっぱ放射性元素とガイガー計数管だな
62 :
デフォルトの名無しさん:2001/03/29(木) 11:10
>コンピュータに数学的な真の乱数なんて無理だろ
全く持ってその通り。がここでは工学的な話をしてるような気もする。
63 :
デフォルトの名無しさん:2001/03/29(木) 14:55
>>58 >完全に決定論的なマシンであるコンピューターは、 特に変則的な動作は苦手です (欠>陥 OS ソフトウェアの場合を除く)。
うまい!
>>62 たとえば周期がいくつ以上なら「真の乱数」としてみとめられるん?
JIS,ISOあたりに規格でもあるとか?
(暗号関係であってもいいような気もする)
65 :
デフォルトの名無しさん:2001/03/29(木) 23:55
>>64 やっぱ使用目的のシステムによるってコトで、
66 :
デフォルトの名無しさん:2001/04/09(月) 22:07
>>64 周期がある乱数は、疑似乱数といって、まともな暗号にはふつう使いません
だから、/dev/randomがあるのれす
67 :
64:2001/04/09(月) 22:48
>>65-66
有限状態オートマトンは周期をもたない数列を生成することはできないんだってば
(厳密に言えばどんなスゴイ暗号ソフトが使ってるのも疑似乱数?)
ただコンピュータに実装されているメモリ量からすれば内部状態の数も
超天文学的数字になるし事実上周期がない数列が作れるとみなしてもいいんだろうけど。
でもCのrand()とか手抜きもいくらでもできるわけで
乱数の品質を計るなんかの基準があってもおかしくはなような気がしたんだ。
68 :
デフォルトの名無しさん:2001/04/10(火) 00:28
>>67 ハァ? どんなに周期が大きくても、ある値から次の値が予測できるようでは、
少なくとも暗号用としては使いものにならないんだって。
だから/dev/randomやらPGPやらは、ちゃんとした乱数発生器(≒人間)を
使ってるんだろ。
ハード的な乱数ってぇと、Z80のRレジスタ使ってたのを思い出すなぁ…
70 :
デフォルトの名無しさん:2001/04/10(火) 01:45
/dev/randomってのは典型的にはどう実装されてるのか
教えてください。
nearly eq to 人間ってことは
バッチ処理マシンでは使えないってこと?
71 :
デフォルトの名無しさん:2001/04/10(火) 02:18
MT(メルセンヌ=ツイスター)法とかいうのが現在最強って聞いたけど
72 :
デフォルトの名無しさん:2001/04/10(火) 22:08
>>70 linuxの場合、簡単に言うと、キー入力、マウス入力、割り込み、
ブロックデバイスアクセスなどのタイミング情報を集めて、
かき混ぜて出来上がり。詳しくはソース読め。
73 :
デフォルトの名無しさん:2001/04/11(水) 10:46
74 :
73:2001/04/11(水) 11:03
そいえば、うちのジョイバッドってテストすると
いつも数値が揺らいでるけど、あれうまく使えないかな
77 :
デフォルトの名無しさん:2001/04/11(水) 16:38
78 :
デフォルトの名無しさん:2001/04/11(水) 17:05
よく判らんけど、CDROMのデータをそのまま読んでもノイズじゃないでしょ
それとも音声としてサウンドカードを通して読むという事?
なら、単純にマイク音量を思いっきりあげてノイズをヒラッタ方がいいと思うけど
ホワイトじゃなくてピンクがかっただと思うし、当然電源周波数とか色々入ると思うけど
適応フィルタで取り除けば緩和はすると思う
79 :
77:2001/04/11(水) 18:02
80 :
デフォルトの名無しさん:2001/04/11(水) 18:06
81 :
デフォルトの名無しさん:2001/04/11(水) 18:37
STLのアルゴリズムのrandom_shuffleで、独自の乱数生成関数を指定できますが
何か良い乱数生成関数を教えてください。
82 :
デフォルトの名無しさん:2001/04/11(水) 20:10
83 :
しお:2001/04/12(木) 18:18
>>80 時間かかっていいなら正しいアプローチかもねぇ。
使いどころが考えにくいけど。バレるし。
84 :
デフォルトの名無しさん:2001/04/13(金) 04:21
>>82 81じゃないけど
いいところ教えてくれてさんくす
GFSR だから M-Sequence と同じで判りやすいね
85 :
名無しさん:2001/05/27(日) 04:49
AESって、なんかNSA用の抜け穴ありそうだ
86 :
デフォルトの名無しさん:2001/05/27(日) 21:26
>>67 周期性を持たない、というだけなら可能じゃないの?
たとえば
1,1,0,1,0,0,1,0,0,0,1,0,0,0,0,...
とか。まあ、この数列でも、「0の数」を示す変数がwrap round
しちゃったら周期的になるけど。
87 :
デフォルトの名無しさん:2001/05/27(日) 21:45
ユーザーが多い端末だったり、WWWサーバだったりしたら、
ps auxwww とかやってそれを種にするとか。
自分専用端末とかだとあんまり意味ないかも。
88 :
デフォルトの名無しさん:2001/05/27(日) 22:41
>>82 Mersenne Twisterなんですが、
>松本-西村はMTを販売用プログラムにも自由に使っていただこうと決めました。そのため、GNU Public Licenseよりも条件のゆるい"Artistic License" の元に配布するコード mt19937.tar を用意致しました。
となってるんですが、Artistic Licenseってどんなのですか?
アーカイブ展開して出てきたライセンス条項読んでみたけど英文なんでよくわかんなかったです。
>>53 下位ビットの方は乱数として不適切だからあまりをつかうのは良くない
と、どっかの本で読んだよ。今はどうか知らないけど
90 :
デフォルトの名無しさん:2001/05/28(月) 00:49
91 :
デフォルトの名無しさん:2001/05/28(月) 01:58
>>1 私も同じようなこと考えています。
コンピューターで質の良い乱数を出すにはどうしたらいいか。
コンピュータは、一定以上乱数を出し続けると内部タイマーがリセットされ
同じ乱数がでてくるようになるみたいなんんです。
実験でのデータで大量の乱数を使いたいのですがが、完全にバラバラで、
長時間出力しつづけてもループしない乱数を出せないものでしょうか。
コンピュータでは無理なんかなぁ
92 :
デフォルトの名無しさん:2001/05/28(月) 02:24
>>91 コンピュータでは云々言う前に、数学の問題ってことをわかってください。
現在のところ、完全にランダムな数を生み出しつづける数式が見つかって
いないので、「計算機」であるコンピュータでは完全にランダムな数を生
み出しつづけるプログラムは作れない。
乱数っぽいものなら計算式で書けるようになってきたので、それでどうに
かコンピュータ上で乱数っぽいものを作れるようになってきた。
それが今まで出てきた線形合同法なりMT法なりです。
完全な乱数を生める計算式を作れたら多分ノーベル賞取れます。
実験のデータとかで使うならMT法がいいと思います。
>>82あたりで出てます。
この擬似乱数は非常に周期が長いため、実験とかで使うぶんには
問題ないのではないでしょうか。
93 :
デフォルトの名無しさん:2001/05/28(月) 02:27
>>91 ありがとうございます。
MT法について勉強してみます。
明日からやることが見つかりました!
94 :
デフォルトの名無しさん:2001/05/28(月) 02:27
95 :
デフォルトの名無しさん:2001/05/28(月) 02:40
円周率って乱数じゃない?
循環しない小数は乱数に使えるかな
97 :
´π`:2001/05/28(月) 02:50
3.141592653589793238462643383279502884967
めるせんぬついすたぁ で十分すぎ
πが循環しないことを証明せよ
100 :
100:2001/05/28(月) 04:19
>>99 いまのところ循環してないからいいんじゃない?
102 :
名無しさん:2001/05/28(月) 07:40
なんか、るーぷしてるぞ〜、みんなかこログよめ〜
乱数が出せないはずのコンピュータで乱数を出すために、
/dev/randomや、PGPはいろいろな小技をつかってるってことで
103 :
デフォルトの名無しさん:2001/05/29(火) 00:27
rand
104 :
デフォルトの名無しさん:2001/05/29(火) 03:00
どなたかが公開してた0-255限定の乱数発生器、結構役に立ちました。
ありがとう。
適当な大きさのファイルを作ってCRCをとり、
その結果や、時間等によって、ファイルを一文字ずつ書きかえるとか…。
それなら線形合同法でもいいじゃん
>>106 一応、まだ出てない案(よね…(^^;)で、
時間や、その他条件に関わらず、
毎回得られる結果を変えようとしてるので許して。
かなり重そうだけど…。
と言う訳で、少し軽くする為に、ファイルの部分を、
メモリ内に常駐させれば、使える速さになる…かな?
…嫌な常駐だな…。
>>100 πは証明がなされたはずですよ
πに関する話題だけのの本数冊
みかけた 理解は出来なかったけど
でもπの2乗が有理数か無理数かは
解ってないそうだ 不思議なものだね
>>101 厳密には超絶数と言うらしい
循環しない小数があったとして、どうやれば乱数にできるかな。
二進数化していって、数桁ごとに区切るか?
CD-ROMから「王仁三郎 言霊リミックス」を読み出せば乱数です。
必要なら他のと混ぜてね