-
2020-09-20 22:57:16
真随机数
自然界中的有很多不确定的物理现象,通过测量这些现象,就可以获得真随机数。比如白噪声的幅值、电子元器件的电压噪声等,真随机数可以通过用硬件对这些参数进行采集获得。
伪随机数
伪随机数序列是用确定性的算法计算出来的周期很长的序列。程序的运行过程是一个确定的过程,每一条指令都是确定的,因此不能产生真的随机数。
说到伪随机数就会说到种子,什么是种子呢,我们可以将种子理解为一个初始值,特定算法根据这个初始值产生一个一定的序列,生成的这个序列“看起来”是随机的,实际上是一个周期很长的确定序列。如果每次的种子设置得相同,那么产生的序列都是相同的。
举个例子,我们可以简单的设置这个种子为某个数,比如1。请看如下代码,用srand()设置种子的值,用rand()产生伪随机数序列,需要包含头文件#include <stdlib.h>
。重复运行下列代码,因为种子相同,所以每次输出的序列都是如图的序列"41 18467 6334 26500 …"。srand(1); // 设置种子的值为1,如果不设置,默认种子为1 for (int i = 0; i < 10; ++i) { cout << rand() << " "; // 输出10个伪随机数 }
如果每次种子设置得不同,那生成的序列也将不同。 如何获得不同的种子呢?
可以用C语言中的库函数time_t time(time_t *seconds)
返回自1970-01-01 00:00:00 UTC 起经过的时间,以秒为单位。这个函数的入参seconds也能保存结果,请看如下代码,输出的t和seconds的值是一样的。time_t seconds; time_t t=time(&seconds); cout << t <<" "<< seconds <<endl; // t和seconds的值是一样的
那么,我们将当前的时间设置为种子,由于时间一直在变,种子就一直在变,每次就能生成不同的伪随机数序列。
time_t t=time(nullptr); srand(t); // 设置种子的值为时间 for (int i = 0; i < 10; ++i) { cout << rand() << " "; }
C++代码示例
题目:将1-100的有序序列变成无序序列,要求每次运行的结果不同。
// 题目:将1-100的有序序列变成无序序列,要求每次运行的结果不同。 void fun(vector<int> &vec) { time_t t = time(nullptr); srand(t); // 设置种子的值为时间 rand(); for (int i = 0; i < 500; ++i) { // 每次随机交换数组中的两位 swap(vec[rand() % 100], vec[rand() % 100]); } } int main() { vector<int> vec(100); for (int i = 0; i < 100; ++i) { vec[i] = i+1; } fun(vec); for (auto it : vec) { cout << it << " "; } cout << endl; system("pause"); }
更多相关内容 -
C#伪随机数加密
2021-03-16 00:55:48摘要:C#源码,加密解密,随机数加密 在使用C#编程,但伪随机数加密一直不知道是怎么实现的,今天研究了一下,看了一个使用伪随机数加密用户名密码的例子,觉得简单易懂,索性把源代码也共享出来,帮助更多想实现C#伪... -
一种基于混沌的伪随机数生成器
2020-12-24 11:37:45一种基于混沌的伪随机数生成器 -
ent:一个伪随机数序列测试程序。 这是原始 Fourmilab 页面的镜像
2021-07-01 02:45:56ent - 一个伪随机数序列测试程序 此页面描述了一个程序ent ,它对存储在文件中的字节序列应用各种测试并报告这些测试的结果。 该程序可用于评估加密和统计采样应用程序、压缩算法以及其他对文件信息密度感兴趣的应用... -
Creat_pseudo-random Numbers_random_逆变法_伪随机数_stickdrq_python_
2021-09-30 15:21:08利用逆变法产生100个(可调整)伪随机数,步骤都在程序中的注释 -
用户友好的伪随机数生成器(PRNG)-JavaScript开发
2021-05-26 04:21:51randoma用户友好的伪随机数生成器(PRNG),这在密码上是不安全的。 安装$ npm install randoma用法const Randoma = require('randoma'); const random =新的Random randoma用户友好的伪随机数生成器(PRNG),这... -
csprng:密码学伪随机数生成器
2021-05-10 14:05:36加密PRNG 为什么 该存储库是我学习如何以各种语言实现CSPRNG的一种方式。 毫无疑问,许多语言已经可以访问CSPRNG,例如JavaScript中的window.crypt.getRandomValues()或Python中的os.urandom() 。... -
Pure_PRNG:在python中生成专业的伪随机数包
2021-05-26 00:16:16在python中生成专业的伪随机数包。 仅实现具有良好统计特性的伪随机数算法。 有一些“方法”可以指定多精度伪随机序列的周期。 实现的伪随机数生成算法 二次同余生成器 三次同余生成器 PCG64_XSL_RR; PCG64_DXSM ... -
用C语言的rand()和srand()产生伪随机数的方法总结
2020-12-22 18:56:52标准库(被包含于中)提供两个帮助生成伪随机数的函数: 函数一:int rand(void); 从srand (seed)中指定的seed开始,返回一个[seed, RAND_MAX(0x7fff))间的随机整数。 函数二:void srand(unsigned ... -
TRIRND:生成 n 个具有三角形密度的伪随机数。-matlab开发
2021-06-01 10:16:54该函数生成具有三角概率密度函数的伪随机数。 -
研究伪随机数序列独立性的均匀偏度法 (1982年)
2021-05-15 11:47:11In this paper,an uniform departureness method for studying the independen-ce of the pseudorandom sequence is developed. This method can mark the indepe-ndence of the pseudorandom sequence better than ... -
伪随机数
2021-07-09 01:07:48伪随机数是用确定性的算法计算出来自[0,1]均匀分布的随机数序列。并不真正的随机,但具有类似于随机数的统计特征,如均匀性、独立性等。在计算伪随机数时,若使用的初值(种子)不变,那么伪随机数的数序也不变。伪...伪随机数是用确定性的算法计算出来自[0,1]均匀分布的随机数序列。并不真正的随机,但具有类似于随机数的统计特征,如均匀性、独立性等。在计算伪随机数时,若使用的初值(种子)不变,那么伪随机数的数序也不变。伪随机数可以用计算机大量生成,在模拟研究中为了提高模拟效率,一般采用伪随机数代替真正的随机数。模拟中使用的一般是循环周期极长并能通过随机数检验的伪随机数,以保证计算结果的随机性。[1]
中文名
伪随机数
外文名
Pseudo-random Number方 法
直接法,逆转法
应 用
程序语言
性 质
名词
伪随机数生成方法
编辑
语音
一般地,伪随机数的生成方法主要有以下3种:
(1) 直接法(Direct Method),根据分布函数的物理意义生成。缺点是仅适用于某些具有特殊分布的随机数,如二项式分布、泊松分布。
(2) 逆转法(Inversion Method),假设U服从[0,1]区间上的均匀分布,令X=F-1(U),则X的累计分布函数(CDF)为F。该方法原理简单、编程方便、适用性广。
伪随机数发生器(3)接受拒绝法(Acceptance-Rejection Method):假设希望生成的随机数的概率密度函数(PDF)为f,则首先找到一个PDF为g的随机数发生器与常数c,使得f(x)≤cg(x),然后根据接收拒绝算法求解。由于算法平均运算c次才能得到一个希望生成的随机数,因此c的取值必须尽可能小。显然,该算法的缺点是较难确定g与c。
因此,伪随机数生成器(PRNG)一般采用逆转法,其基础是均匀分布,均匀分布PRNG的优劣决定了整个随机数体系的优劣[7]。下文研究均匀分布的PRNG。
伪随机数程序实例
编辑
语音
C语言程序例
伪随机数下面看这样一个C程序://rand01.c
#include
static unsigned int RAND_SEED;
unsigned int random(void)
{
RAND_SEED=(RAND_SEED*123+59)%65536;
return(RAND_SEED);
}
void random_start(void)
{
int temp[2];
movedata(0x0040,0x006c,FP_SEG(temp),FP_OFF(temp),4);
RAND_SEED=temp[0];
}
main()
{
unsigned int i,n;
random_start();
for(i=0;i<10;i++)
printf("%u\t",random());
printf("\n");
}
这个程序(rand01.c)完整地阐述了随机数产生的过程:
首先,主程序调用random_start()方法,random_start()方法中的这一句我很感兴趣:
movedata(0x0040,0x006c,FP_SEG(temp),FP_OFF(temp),4);
伪随机数理论推导这个函数用来移动内存数据,其中FP_SEG(far pointer to segment)是取temp数组段地址的函数,FP_OFF(far pointer to offset)是取temp数组相对地址的函数,movedata函数的作用是把位于0040:006CH存储单元中的双字放到数组temp的声明的两个存储单元中。这样可以通过temp数组把0040:006CH处的一个16位的数送给RAND_SEED。
random用来根据随机种子RAND_SEED的值计算得出随机数,其中这一句:
RAND_SEED=(RAND_SEED*123+59)%65536;
是用来计算随机数的方法,随机数的计算方法在不同的计算机中是不同的,即使在相同的计算机中安装的不同的操作系统中也是不同的。我在linux和windows下分别试过,相同的随机种子在这两种操作系统中生成的随机数是不同的,这说明它们的计算方法不同。
我们明白随机种子是从哪儿获得的,而且知道随机数是怎样通过随机种子计算出来的了。那么,随机种子为什么要在内存的0040:006CH处取?0040:006CH处存放的是什么?
学过《计算机组成原理与接口技术》这门课的人可能会记得在编制ROM BIOS时钟中断服务程序时会用到Intel 8253定时/计数器,它与Intel 8259中断芯片的通信使得中断服务程序得以运转,主板每秒产生的18.2次中断正是处理器根据定时/记数器值控制中断芯片产生的。在我们计算机的主机板上都会有这样一个定时/记数器用来计算当前系统时间,每过一个时钟信号周期都会使记数器加一,而这个记数器的值存放在哪儿呢?没错,就在内存的0040:006CH处,其实这一段内存空间是这样定义的:
TIMER_LOW DW ? ;地址为 0040:006CH
TIMER_HIGH DW ? ;地址为 0040:006EH
TIMER_OFT DB ? ;地址为 0040:0070H
时钟中断服务程序中,每当TIMER_LOW转满时,此时,记数器也会转满,记数器的值归零,即TIMER_LOW处的16位二进制归零,而TIMER_HIGH加一。rand01.c中的
movedata(0x0040,0x006c,FP_SEG(temp),FP_OFF(temp),4);
正是把TIMER_LOW和TIMER_HIGH两个16位二进制数放进temp数组,再送往RAND_SEED,从而获得了“随机种子”。
可以确定的一点是,随机种子来自系统时钟,确切地说,是来自计算机主板上的定时/计数器在内存中的记数值。这样,我们总结一下前面的分析,并讨论一下这些结论在程序中的应用:
1.随机数是由随机种子根据一定的计算方法计算出来的数值。所以,只要计算方法一定,随机种子一定,那么产生的随机数就不会变。
C++程序例
伪随机数理论推导看下面这个C++程序://rand02.cpp
#include
using namespace std;
int main()
{
unsigned int seed=5;
srand(seed);
unsigned int r=rand();
cout<
return 0;
}
在相同的平台环境下,编译生成exe后,每次运行它,显示的随机数都是一样的。这是因为在相同的编译平台环境下,由随机种子生成随机数的计算方法都是一样的,再加上随机种子一样,所以产生的随机数就是一样的。
2.只要用户或第三方不设置随机种子,那么在默认情况下随机种子来自系统时钟(即定时/计数器的值)
C++程序例2
看下面这个C++程序://rand03.cpp
#include
#include
using namespace std;
int main()
{
srand((unsigned)time(NULL));
unsigned int r=rand();
cout<
return 0;
}
这里用户和其他程序没有设定随机种子,则使用系统定时/计数器的值做为随机种子,所以,在相同的平台环境下,编译生成exe后,每次运行它,显示的随机数会是伪随机数,即每次运行显示的结果会有不同。
3.建议:如果想在一个程序中生成随机数序列,需要至多在生成随机数之前设置一次随机种子。
生成一个随机字符串
看下面这个用来生成一个随机字符串的C++程序:(原来的程序我编译不了,就改了改,加了一些头文件)(我不是上面那个括号里的人。我又对源程序进行了一下简化,可以实现相同的功能)#include
#include
#include
#define n 20
using namespace std;
int main()
{
srand (time(0));
for (int i=0;i
cout<
return 0;
}
伪随机数发生器
你可能会遇到这种情况,在VB中,在使用timer控件编制程序的时候会发现用相同的时间间隔生成的一组随机数会显得有规律,而由用户按键command事件产生的一组随机数却显得比较随机,为什么?根据我们上面的分析,你可以很快想出答案。这是因为timer是由计算机时钟记数器精确控制时间间隔的控件,时间间隔相同,记数器前后的值之差相同,这样时钟取值就是呈线性规律的,所以随机种子是呈线性规律的,生成的随机数也是有规律的。而用户按键事件产生随机数确实更呈现随机性,因为事件是由人按键引起的,而人不能保证严格的按键时间间隔,即使严格地去做,也不可能完全精确做到,只要时间间隔相差一微秒,记数器前后的值之差就不相同了,随机种子的变化就失去了线性规律,那么生成的随机数就更没有规律了,所以这样生成的一组随机数更随机。这让我想到了各种晚会的抽奖程序,如果用人来按键产生幸运观众的话,那就会很好的实现随机性原则,结果就会更公正。
总结
1.计算机的伪随机数是由随机种子根据一定的计算方法计算出来的数值。所以,只要计算方法一定,随机种子一定,那么产生的随机数就是固定的。
2.只要用户或第三方不设置随机种子,那么在默认情况下随机种子来自系统时钟。
伪随机数生成器缺点
编辑
语音
重复做N=10000次试验,每次产生S=20与S=100个随机分布的样本,同时采用Kolmogorov- Smirnov假设检验(hypothesis test)来确定样本是否满足均匀分布。规定:
① 0假设(null hypothesis)为样本服从均匀分布;② 1假设(alternative hypothesis)为样本不服从均匀分布。
采用P值(∈[0, 1])衡量,P值越趋近于0,表示越有理由拒绝0假设,即样本不服从均匀分布;P值越趋近于1,表示越有理由接受0假设,即样本服从均匀分布。
随着P值下降,样本也越来越不服从均匀分布。实践中希望P值越大越好。然而统计学的结论显示,P值一定服从均匀分布,与N、S大小无关,这表明由于随机性,总会出现某次抽样得到的样本不服从、甚至远离均匀分布。另外,样本大小的不同,造成检验标准的不同,直观上看S=100对应的均匀分布普遍比S=20对应的更均匀。因此,小样本情况下均匀分布PRNG的差异性尤为严重。
词条图册
更多图册
参考资料
1.
陆雄文.管理学大辞典:上海辞书出版社,2013年
-
基于细胞神经网络的伪随机数生成方法
2021-01-14 13:48:40为了克服有限精度效应对混沌系统的退化影响,改善所生成随机序列的统计性能,设计了一种新的基于六维CNN(细胞神经网络)的64 bit伪随机数生成方法。在该方法中,通过控制六维CNN在每次迭代过程中的输入输出,改善了... -
C#伪随机数加密完整源码(十分经典)
2019-03-07 10:23:22C#伪随机数加密完整源码(十分经典) -
PRNG(伪随机数生成器)
2021-04-01 22:39:15用于在VB / VBScript / ASP页中创建随机数的ActiveX控件 -
伪随机数随机性的一种新检验 (2005年)
2021-05-07 11:44:05伪随机数通过的随机性检验越多,说明其随机性越好.利用生产的随机数精度固定这一特点,根据小数点后面n个数字之和,提出了尾数和的概念,并给出了求尾数和分布频数的算法.根据尾数和分布概率提出了一种检验伪随机数的新... -
OpenRK:用于生成伪随机数的软件开发工具包-开源
2021-05-31 03:59:28OpenRK - Open Randomness Kit 库是一组与伪随机数相关的例程,用于 C 和 C++ 程序员的数值计算。 它是用 C 语言从头开发的,提供了一个现代且易于使用的应用程序编程接口 (API),有助于缩短开发时间并帮助您获得更... -
伪随机数算法
2021-02-14 21:41:20伪随机数算法 -
C#使用伪随机数实现加密用户密码的方法
2020-09-04 08:29:49主要介绍了C#使用伪随机数实现加密用户密码的方法,对于开发C#会员系统或者程序安全问题都有一定的参考借鉴价值,需要的朋友可以参考下 -
逻辑回归matlab代码-PredictingPRNGs:使用机器学习技术预测伪随机数生成器
2021-05-28 01:11:28使用机器学习技术预测伪随机数生成器 要运行一个学习者的单个实例,请使用exampleKNN.m脚本(例如,运行KNN)。 要重新运行实验,请运行deployConfig.m。 我们总共实施了五名学习者: 随机抽样-按比例随机抽取训练... -
素数的一个特殊性质及其用于伪随机数生成的方法 (2003年)
2021-05-13 12:21:04提出素数的一个特殊性质,...基于上述理论分析,提出一种伪随机数生成的新方法――超素数法,统计结果表明本文方法具有良好的统计特性,由此得到的伪随机数序列可用作伪随机数发生器,文中给出了计算方法和数值示例。 -
PHP的伪随机数与真随机数详解
2020-12-18 11:59:51首先需要声明的是,计算机不会产生绝对随机的随机数,计算机只能产生“伪随机数”。其实绝对随机的随机数只是一种理想的随机数,即使计算机怎样发展,它也不会产生一串绝对随机的随机数。计算机只能生成相对的随机数... -
伪随机数的独立同分布检验
2020-02-07 10:41:30伪随机数的独立同分布检验,邹永杰,,伪随机数在蒙特卡罗模拟、密码学和自动控制等领域都有重要应用,因此对随机数检验是保证伪随机数质量的重要措施。本文给出的BDS检 -
matlab平方取中法、线性同余法、组合发生器生成三种伪随机数
2021-04-22 09:23:27matlab平方取中法、线性同余法、组合发生器生成三种伪随机数,并进行均匀性检验 -
基于量子随机游动的新型伪随机数发生器
2021-03-02 04:22:22基于量子随机游动的新型伪随机数发生器 -
The Random Number Grand Challenge 随机数大挑战 :解码伪随机数序列-数据集
2021-03-12 15:19:35高质量的伪随机数生成形成了所有计算的基础。从密码学到金融市场再到粒子物理学,我们对随机数的信任助长了现代经济,并允许技术不断发展。机器学习在识别统计模式方面非常强大。本数据集要求您运用机器学习技能来... -
伪随机数产生程序
2013-04-19 15:35:55产生伪随机数的一个C程序,可以修改产生范围。 -
通过密码学中的伪随机数生成器和散列进行保护:回顾-研究论文
2021-06-10 12:50:06您绝不能说您的消息是完全安全的,即任何第三方都可以在处理的任何时间/阶段攻击您的消息。 对于发送机密消息,安全功能对于避免任何未经授权的访问至关重要。 正如 Koblitz 爵士所描述的那样,我们必须在 ECC 中... -
动态分组混沌伪随机数发生器
2021-04-30 12:41:45为了克服计算机处理数据的有限精度导致混沌特性退化的缺陷,改善随机数发生器输出序列的随机性能,设计了一种新的基于logistic混沌映射生成伪随机数的方法。在提出的方法中,采用四个一维logistic混沌映射,每次迭代... -
正态分布和正分布伪随机数:正高斯变量的模拟。-matlab开发
2021-05-30 22:25:11此函数生成根据截断的正态分布(或通过转换为具有正支持的正态分布)分布的随机变量。 这种问题对于用 MCMC 方法生成变量特别有趣。 我们使用混合接受-拒绝算法,即经典的接受-拒绝算法使用多个提议分布,每个提议...