欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

随机序列的算法_MySQL

程序员文章站 2022-06-12 12:06:03
...
找到了两个算法, 第一个很简单, 但可惜不是随机的, 第二个是典型的伪随机数算法, 可惜要用到2的几百万次方这样巨大的整数, 真痛苦
要是有UNIX上计算密码的源代码就好了

第一种做法:
f(k) = (k*F(N-1)) mod F(N)
其中,
k是一个序列号, 就是要取的那个数的顺序号
F(N)是这样一个序列 F(0) = 0, F(1) = 1, F(N+2) = F(N+1)+F(N) (for N>=0)

第二种做法

V = ( ( V * 2 ) + B .xor. B ... )(Mod 2^n)
N+1 N 0 2
V是要取的随机数, B是个种子, n是随机数的最大个数

原来这个问题, 很高难, 不少数学高手都为解决这个问题写了论文, 咳咳, 偶真是个白痴

呵呵, 效果肯定是不错啦, 因为用不到很大的表.
至于应用是这样的, 比如, 你要给每个用户在注册的时候一个ID但有不希望用户在看到自己的ID的时候能知道其他用户的ID, 如果用SEQUENCE来生成ID的话, 一个用户只要把自己的ID减1就能得到其它用户的ID了. 所以要用随机数来做ID, 这样用户很难猜到其他用户的ID了.

当然主要的问题是, 随机数可能重复. 因此希望使用一个随机数做种子用它来确定一组"无规律"的自然数序列, 并且在这个序列中不会出现重复的自然数. 在这里使用的方法生成的序列并不是没有规律的, 只不过这个轨律很难被发现就是了.
Xn+1 = (aXn + b) mod c (其中, abc通常是质数)是一种被广泛使用的最简单的随机数发生算法, 有研究表表明这个算法生成的随机数基本上符合统计规律, JAVA, BORLAND C等用的都是这个方法, 一般只要保证第一个种子是真正的随机数就行了,

下面来说一下重复的问题,
上述方法会有可能出现重复, 因为当(aXn + b)有可能是同样的数或者说余数相同的数, 因此要想不重复就得变形
偶想到的方法是
Xn=(a*n + b) mod c n是一个在1到c之间的整数, a*n + b就是一个线性公式了, 且若n不同则a*n + b也不同, 它们除上质数c得到的余数也肯定不同, 因为 若不考虑a和b而只有n的时候, 每次的结果都是n,而线性公式, 只不过移动了这条直线的位置和斜率而已, 每个结果仍然不会相同的,
为了增加不可预计性, 偶又为上面那个公式设计了, 随机数种子, 于是就变成了这个样子
F(N)=(随机数*(N+随机数))MOD 一个质数
这样就能够产生 1到选定质数之间的一个"无规律"的自然数序列了, 只要改变随机数就能改变序列的次序

在应用的时候, 要把随机数种子和最后用到的序列号保存到一个表里, 每此使用的时候取出来算好, 再把序列号更新一下就可以了
具体地说, 就是可以建一个表来保存每个序列的随机数种子, 然后再为这个序列建一个SEQUENCE就行了
然后就
SELECT MOD(序列控制表.随机数*(SEQ.NEXTVAL+序列控制表.随机数)),序列控制表.质数)
FROM 序列控制表
WHERE 序列控制表.序列ID=XX
就OK了
注意 序列控制表.质数 决定了序列的范围

相关标签: k