请教一个伪随机数生成问题。
假设网络中的一个计算机结合,现在需要每个计算机生成一个伪随机数(例如32位数),但是不想这些计算机间相互通信,有没有什么算法或思想使这些计算机生成的伪随机数不相互冲突(即在一段时间和网络范围内,生成的伪随机数个不相同,或相同的概率很小)
?
如果有什么相关的文献或思想,请赐教!
谢谢!
[解决办法]
用哈希算法,每台机器给一个的熵池(可以相同) +一个不同的字符串 这样理论上不存在相同的可能性
例如
机器1 hash( "i am num1 " + 当前时间)
机器2 hash( "i am num2 " + 当前时间)
[解决办法]
直接用windows的GUID生成算法算了。号称全球计算机随便用多少年都不可能重复的。
嫌长的话,对它再散列一下或者干脆生成32位检验和即可。
[解决办法]
晕,没仔细想。上面关于散列或为GUID生成短检验和的说法是错误的。那最多是一个得到可靠的伪随机数的方法。
如果是32位数就不可能没有冲突。
这种情况下不冲突的前提就是:相对于生成的实例数目来说,可选数值的范围非常广,并且数值的选取方法在这个范围内分布均匀,以至于重复概率极小,可近似看作不会出现。
比如你可以看看windows的GUID有多少位。
或者可以给计算机编号。生成的32位数的前几位是这个编号,后面几位不用随机,按顺序排下来即可。
当然,这个编号也许可以利用下网卡地址或硬盘ID——32位确实太短了,很难保证不冲突的。
[解决办法]
其实很简单。只要保留一部分数据作为计算机ID就可以了。
比如总共只有不超过100台的计算机。对这些计算机全部编号,最多7bit.
然后其余的32-7=25位采用随机数。然后两部分数据合并就可以了。
[解决办法]
mathe()的方法就是预先给计算机编号,再结合本机一定位数内生成的随机数来生成部分随机部分固定的一个随机数,这个结合机制也是可以自定义的,比如可以插位结合或者置高位、置低位、置中间部分位等等。
[解决办法]
利用线性同余式
n[j+1] =n[j] * a+c (mod m) ,
只要适当选取n[0],a,c,m
就可生成2^k个完全不同的伪随机数n[j],j=0..2^k-1。
参看:
http://zhidao.baidu.com/question/540840.html?md=3
[解决办法]
GUID算法似乎可以在 com本质论 一书中找到。
[解决办法]
RFC 4122
[解决办法]
GUID并不保证不重复,仅仅是因为可选数据量大而变成重复概率小,所以要减少数据重复的几率还有一种方法就是提高数据量,比如提高成64位数(两次生成32位来合成一个)。
[解决办法]
某男性公民身份号码本体码为34052419800101001,首先按照公式⑴计算:
∑(ai×Wi)(mod 11)……………………………………(1)
公式(1)中:
i----表示号码字符从由至左包括校验码在内的位置序号;
ai----表示第i位置上的号码字符值;
Wi----示第i位置上的加权因子,其数值依据公式Wi=2(n-1)(mod 11)计算得出。
i 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
ai 3 4 0 5 2 4 1 9 8 0 0 1 0 1 0 0 1 a1
Wi 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 1
ai×Wi 21 36 0 25 16 16 2 9 48 0 0 9 0 5 0 0 2 a1
根据公式(1)进行计算:
∑(ai×Wi) =(21+36+0+25+16+16+2+9+48++0+0+9+0+5+0+0+2) = 189
189 ÷ 11 = 17 + 2/11
∑(ai×Wi)(mod 11) = 2
然后根据计算的结果,从下面的表中查出相应的校验码,其中X表示计算结果为10:
∑(ai×WI)(mod 11) 0 1 2 3 4 5 6 7 8 9 10
校验码字符值ai 1 0 X 9 8 7 6 5 4 3 2
根据上表,查出计算结果为2的校验码为所以该人员的公民身份号码应该为 34052419800101001X。
这个原理行不行