随机数在区块链中作用以及使用过程[3]:
-
在比特币区块链中,所有参与节点都在遍历寻找一个随机数,节点算力输出越大就越有可能遍历到这个随机数,也就能够抢到这一轮的记账权,这个过程通常被称为“挖矿”。各参与节点在遍历随机数的过程中也在不断地验证其他节点的交易信息,抢到记账权的节点会把所有相关的信息广播出来,全网中所有参与节点在共同验证了广播出来的信息之后就会形成一个区块,紧接在上一个区块的后面,形成一条区块数据链。
-
随机数如何抵抗重放攻击?
- 随机数抵御重放攻击,因为只需要对比一下随机数是否一致就能够知道这个消息是不是已经发送过了
现代信息安全体制做到以下几点,使得系统的安全性要求不受影响:
- 密码体制和算法本身可以被公开;
- 访问策略可以公布;
- 密码设备可能丢失;
- 在比特币的安全体制中:完全依赖于随机数序列的生成效率和质量。
应用广泛:
- 数据加密
- 密钥管理
- 公钥和私钥的产生
- 电子商务
- 数字签名
- 身份鉴定
- 蒙特卡罗仿真等
随机数的分类[1]、[2]:
1.伪随机:
-
定义:
- 用确定性的算法计算出来自[0,1]均匀分布的随机数序列;
- 并不真正的随机,但具有类似于随机数的统计特征,如均匀性、独立性等。
-
特性:模拟中使用的一般是循环周期极长并能通过随机数检验的伪随机数,以保证计算结果的随机性。
-
种类:
- 线性同余,
- 平方取中,
- 其他
-
产生随机数的过程[2]:
-
第一步:假设我们手头已经有一串数字,我们称它们为种子。对这些种子用递归法,“随机地(其实并不是)”生成一连串0到某个自然数N之间的自然数。
- 线性同余法(比如
RANDU
) (但是如果是multiplicativ
的话,在n维空间里的点都在有限个超平面里,这些伪随机数的独立性不佳)
-
梅森旋转法(循环周期长,速度快)
-
平方取中法(速度快,但是很容易生成循环周期短的数列,还有很多不动点)[4]
float Xn=12345; //Seed & Iter float Rn; //Return Val void InitSeed(float inX0) { Xn=inX0; } float MyRnd() { //implementation: Xn+1=(Xn^2/10^S)(mod 10^2S) Xn=(int)fmod((Xn*Xn/pow(10,S)),pow(10,2*S));//here can's use % //implementation: Rn+1=Xn+1/10^2S Rn=Xn/pow(10,2*S); return Rn; }
-
Lagged Fibonacci generator(独立性不好)
- 线性同余法(比如
-
第二步:把这些随机生成的自然数转换成0到1之间的实数 (比如通过除以N来得到)。如果这样生成的伪随机数能够通过许多不同的统计检验,达到了“以假乱真”的程度,我们就厚脸皮地认为自家程序已经聪明地会生成[0,1]上均匀分布的独立样本啦!
-
统计检验:
在一定可靠性程度上对一个或多个总体分布的原假设作出拒绝还是不拒绝(予以接受)结论的程序。
-
差异显著性检验:
决定常取决于样本统计量的数值与所假设的总体参数是否有显著差异。在一定可靠性程度上对一个或多个总体分布的原假设作出拒绝还是不拒绝(予以接受)结论的程序。——最终结果是拒绝或者不拒绝
-
-
第三步:利用这串“从零到一均匀分布的随机数”,把它们用某些算法来转换成其他分布的随机数——转换的是固定的函数并不是想转换什么函数就可以转换
-
逆函数法Inverse transform sampling(为了提高速度,会用数值方法取逆函数,这样做的缺点是会产生误差)
# 从均匀分布转换到其分布函数的时候,这样的映射就使得最后就不是均匀分布,使别人看起来就是随机的了 R = np.random.uniform(rmin, rmax, N) # 获得随机均匀分布的从rmin-rmax的区间 X = invCDF(R) #最终结果,后面的都是画图的以及相关处理
-
Von Neumann舍选法Rejection samplin(提高其效率的关键是讲其中的常数C取得越小越好)
''' 基本的rejection methold步骤如下: 1. Draw x uniformly from [xmin xmax] 2. Draw x uniformly from [0, ymax] 3. if y < w(x),accept the sample, otherwise reject it 4. repeat 即落在曲线w(x)和X轴所围成区域内的点接受,落在该区域外的点舍弃。 例子:下面的代码使用basic rejection sampling methold在区间[0, 10]上生成随机数,其概率密度近似为P(x)=e-x ''' # 循环舍弃接收点 while (accepted < N): # pick a uniform number on [xmin, xmax) (e.g. 0...10) x = np.random.uniform(xmin, xmax) # pp(x) # pick a uniform number on [0, ymax) y = np.random.uniform(0, ymax) # Do the accept/reject comparison if y < P(x): samples[accepted] = x accepted += 1 count += 1 #计算出最后循环的次数
-
Box Muller算法(Box 生成正太分布)
-
Marsaglia polar method (对Box Muller算法的改进,不需要用到sin和cos函数)
-
Marsaglia-Bray method(生成正态分布,97%的情况下无需用到复杂函数)
-
-
-
产生伪随机数需要注意的地方:
- 假如生成的随机数所处的分布为 0-1 区间上的均匀分布。不是 0-1 区间怎么办? 除以 (high-low), 再加上 low 就可以完成任务。我们需要的随机数序列应具有非退化性,周期长,相关系数小等优点。
-
伪随机数的意义:如果不考虑浮点精度,伪随机数和真随机的统计规律完全一致,也就是人类无法通过不断尝试并统计来判断随机数产生器是伪随机还是真随机,当赝品和真品各方面表现都一致的时候,实用角度就不需要真品了。纠结产生方式没有意义的。
2.真随机:
- 真正的随机数是使用物理现象产生的:比如掷钱币、骰子、转轮、使用电子元件的噪音、核裂变等等,这样的随机数发生器叫做物理性随机数发生器,它们的缺点是技术要求比较高。 没有规律并且结果不可以预料[5];
- Unix 内核中的随机数发生器(/dev/random),理论上它能产生真随机。即这个随机数的生成,独立于生成函数,这时我们说这个随机数发生器是非确定的
- 具体来讲,Unix 维护了一个熵池,不断收集非确定性的设备事件,即机器运行环境中产生的硬件噪音,来作为种子。
3.(赝随机数)计算机无法生成真随机的原因:
-
在计算机程序中,不存在“不确定”的数字,只有确定的“1”和“0”。基于这种特性,计算机无法生成“真正的(不确定的)随机数”——赝随机数
-
程序和算法本身不能产生真随机,但是我们想办法可以迂回产生统计意义上的真随机。通过输入一个真正意义上的随机数