用伪随机数建造真的

         “应用密码学”作者Bruce Schneier 对随机序列的定义是:
                                      (1)看起来像随机数
                                      (2)不可预测
                                      (3)不可重复产生
         随机数由性质相同的数组成,单个或几个数不能说是随机数。所以一般又叫随机数组。它们有一些有趣的性质:随机数加、减、乘常数后还是随机数,自行相加、相减、相乘后还是随机数,对随机数组作有规律的变换丝毫不能改变它,就是说变来变去还是随机数组。
         加密解密就是利用随机数加、碱、乘常数后还是随机数的性质而实现的,它可以吞没数字和释放数字。
         什么是看起来像随机数,肯定是杂乱无章的,如果看到明显的规律那肯定不是随机数,一般说的好的随机数,应该是分布均匀的,体现在数组的代数和的平均值接近数组的最大值除以2,且数组越大越明显,但任取一小段肯定是不均匀的。它们服从统计规律,可以通过统计来分析它们。
          不可预测和不可重复产生是相关的,能重复产生就可以预测,自然界里“数组”的一个例子,就是圆周率的小数尾数,它分布均匀,没有周期,无穷无尽,如果我们只知数组不知来源可以将它作为1位10进制随机数组,但知道来源它就是可以重复产生,可以预测的,就不能作为随机数组,看来随机数组是有相对性的。所有随机函数都只能产生伪随机数组,就象我们使用随机函数产生数组,如果在其周期之内使用,并隐藏其发生方法,则在我们这里数组是不随机的,如果破解者搞不清数据的来历,那在他那里就是随机的,这样就够了。但是我们仍不放心,因为他们有复现随机数组的可能性。例如你使用随机数函数并隐藏了种子,破解者只要知道你用的函数就够了,他也许可以做出整个周期的数组,并利用数组攻击你,那时你用什么种子也没有用,但实际上,如果周期很长,他用高速计算机搞到老也不可能查完一遍周期内的数值,这种假的跟真的也差不多。对一般用户来说是真随机数还不够,要对破解者也是才行。
          真随机数的产生是很容易的,一个骰子(色子)就是个6进制数组发生器,在6个面上标记0、1、2、3、4、5,投一次记一个数,6进制数组就这样产生了。如果有十个面,就可以得出10进制数了,这里必须有人做一些运动,才能完成这个过程。可否用计算机来模拟这个过程?计算机这种严格按运算逻辑的东西行吗?让我们来设法实现它。
真随机数组的产生
         我们模拟骰子(色子)来产生 6进制数组,例如做600个数的随机数组,先建一个有序数组它是这样排列的,0、1、2、3、4、5、0、1、2、3、...... 一共600个数,也就是sz[0]......sz[599]。在此范围内我们随机抽取两个sz[i] 和 sz[j],让它们的数值交换,当这个过程做的足够多时,数组就变成随机数组了。交换的次数少了不行,有的地方可能还没有触及,那就会有原来规律性的残余,如何判断呢?例如你可以做图,以序列号为 x,数值为 y,开始时图形为升序的三角波形,当变成无规律的杂乱波形时就可以了,如果是人为的,现在已经完成任务了。如何用计算机来完成?还是借助随机函数吧,使用时间(运行时间、系统时间)相关的数做种子,让它产生0到599之内的随机数,用它们作序列号,做数值交换,直到变得杂乱无章,以数组长度为周期,产生随机数并作交换,算作一次处理。做几个按钮,每个按钮对应一种随机函数处理一次,还有一些按钮对应着有规律变换,例如原排列是1、2、3、1、2、3......,变成3、1、2、3、1、2......就是一种有规律变换,恰当使用也可以加速融合。现在你随便去按这些按钮吧,真随机数就这样产生了。
随机数组的检验
         什么时候交换是个头啊?可以通过检验判断。方法众多仅举一例:测量两个相同元素相继出现的几率,显然是1/6,乘以600得到10,也就是两个相同元素相继出现的次数应该在10附近,到时候再多操作也只能使出现的次数在10附近左右摆动,这说明数组已经均匀了,或者说均匀度已经饱和了,再做下去已经没有意义了。
         再进一步,由时间作种子的随机函数,给按钮随意排序,并控制去按这些按钮,执行不同操作方案,直到检测合格为止,你就可以坐享其成了。
         尽管上面“随机抽取两个序号使它们的数值交换”是用随机函数来完成的。但也不可能使数组向有序化发展,这里一种自然规律在起作用,就是“熵增加原理”,自然作用下有序向无序发展是不可逆的过程,例如你整天洗纸牌,也不可能有一天发现是顺序的了,墨水滴倒水盆里会逐渐扩散,而再也没有机会聚成一滴了。所以我们用不可预料的数作种子,开动几个随机函数去搅动数组的序列也是不可逆的,由于排序是多种因素决定的,所以要想重复实现是不可能的,例如,按了哪些按钮、多少次、顺序如何、时间间隔如何等。这样就保证了数组的随机性。这个过程是不可再现的,计算机作为多任务系统,不能保证同一段程序运行时间精密一致,也就是说与计算机本身的状态有关,而运行时间又关系到其它种子的数值,所以是不可复现的。
          随机函数如果性能不好,将使效率降低,甚至不能将有序数组变为无序,尤其不要让数组长度大于随机函数的周期,如果遇到这样的情况,可以在适当的位置,重新设置种子值。这个方法也是检验随机函数的利器。这里生成的随机数组是一种可以更新的资源,用过以后再作交换则可以成为全新的。
          将此种方法命名为《序列数交换法》。希望对需要用真随机数的朋友有帮助。
 但是真随机数并不一定便于应用,还是自己控制随机函数种子好些,只要你加入些不确定因素即可,你可以使用密码来控制种子的数值,而密码是运行后输入的,根本不出现在没有运行的程序里,这样对你来说数组是伪随机数组,但在破解者那里就是真随机数组了,这样的随机数组可以称为单向真随机数组吧。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值