伪随机性(英语:Pseudorandomness)是一个过程似乎是随机的,但实际上并不是。伪随机数是看似随机实质是固定的周期性序列,也就是有规则的随机。

什么是随机数

随机数在计算机应用中使用的比较广泛,最为熟知的便是在密码学中的应用。随机数有3个特性,具体如下:

随机性:不存在统计学偏差,是完全杂乱的数列

不可预测性:不能从过去的数列推测出下一个出现的数

不可重现性:除非将数列本身保存下来,否则不能重现相同的数列

Random算法

Random的使用是把要随机的集合顺序排列,从集合中随机挑选

Random详细用法请看我这篇文章Java中Random的用法

Shuffle算法

Shuffle算法和排序算法正好相反,是从有序到乱序的一个过程,俗称洗牌算法。

在Java中,有现成的shuffle算法实现,即Collections类中的两个重载的shuffle方法:

public static void shuffle(List> list) {

Random rnd = r;

if (rnd == null)

r = rnd = new Random();

shuffle(list, rnd);

}

private static Random r;

public static void shuffle(List> list, Random rnd) {

int size = list.size();

if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {

for (int i=size; i>1; i--)

swap(list, i-1, rnd.nextInt(i));

} else {

Object arr[] = list.toArray();

// Shuffle array

for (int i=size; i>1; i--)

swap(arr, i-1, rnd.nextInt(i));

// Dump array back into list

ListIterator it = list.listIterator();

for (int i=0; i

it.next();

it.set(arr[i]);

}

}

}

真随机与伪随机

随机数分为真随机数和伪随机数,我们程序使用的基本都是伪随机数,其中伪随机又分为强伪随机数和弱伪随机数。

真随机数,通过物理实验得出,比如掷钱币、骰子、转轮、使用电子元件的噪音、核裂变等。需要满足随机性、不可预测性、不可重现性。

伪随机数,通过一定算法和种子得出。软件实现的是伪随机数。

强伪随机数,难以预测的随机数。需要满足随机性和不可预测性。

弱伪随机数,易于预测的随机数。需要满足随机性。

上面介绍Random算法和Shuffle算法的时候,代码实现都是伪随机算法。可以这样说:

只要这个随机数是由确定算法生成的,那就是伪随机。只能通过不断算法优化,使你的随机数更接近随机。

有限状态机不能产生真正的随机数的,所以,现代计算机中,无法通过一个纯算法来生成真正的随机数,无论是哪种语言,单纯的算法生成的数字都是伪随机数,都是由可确定的函数通过一个种子,产生的伪随机数。

这也就意味着,如果知道了种子,就可以推断接下来的随机数序列的信息。这就有了可预测性。

那么真随机数怎么产生的呢?

通过真实随机事件取得的随机数才是真随机数。

真正的随机数是使用物理现象产生的:比如掷钱币、骰子、转轮、使用电子元件的噪音、核裂变等等。这样的随机数发生器叫做物理性随机数发生器,它们的缺点是技术要求比较高,效率低。

现有的真随机数生成器,比如PuTTYgen的随机数是让用户移动鼠标达到一定的长度,之后把鼠标的运动轨迹转化为种子;Intel通过电阻和振荡器来生成热噪声作为信息熵资源;Unix/Linux的dev/random和/dev/urandom采用硬件噪音生成随机数;

所以,要想生成真的随机数,是无法用任何一个纯算法实现的。都需要借助外部物理现象。

Java中的随机数生成器

Java语言提供了几种随机数生成器,如前面提到的Random类,还有SecureRandom类。

伪随机数生成器

伪随机数发生器采用特定的算法,将随机数种子seed转换成一系列的伪随机数。伪随机数依赖于seed的值,给定相同的seed值总是生成相同的随机数。伪随机数的生成过程只依赖CPU,不依赖任何外部设备,生成速度快,不会阻塞。

Java提供的伪随机数发生器有java.util.Random类和java.util.concurrent.ThreadLocalRandom类。

Random类采用AtomicLong实现,保证多线程的线程安全性,但正如该类注释上说明的,多线程并发获取随机数时性能较差。

多线程环境中可以使用ThreadLocalRandom作为随机数发生器,ThreadLocalRandom采用了线程局部变量来改善性能,这样就可以使用long而不是AtomicLong,此外,ThreadLocalRandom还进行了字节填充,以避免伪共享。

强随机数发生器

强随机数发生器依赖于操作系统底层提供的随机事件。强随机数生成器的初始化速度和生成速度都较慢,而且由于需要一定的熵累积才能生成足够强度的随机数,所以可能会造成阻塞。熵累积通常来源于多个随机事件源,如敲击键盘的时间间隔,移动鼠标的距离与间隔,特定中断的时间间隔等。所以,只有在需要生成加密性强的随机数据的时候才用它。

Java提供的强随机数发生器是java.security.SecureRandom类,该类也是一个线程安全类,使用synchronize方法保证线程安全,但jdk并没有做出承诺在将来改变SecureRandom的线程安全性。因此,同Random一样,在高并发的多线程环境中可能会有性能问题。

在linux的实现中,可以使用/dev/random和/dev/urandom作为随机事件源。由于/dev/random是堵塞的,在读取随机数的时候,当熵池值为空的时候会堵塞影响性能,尤其是系统大并发的生成随机数的时候。

真随机数发生器

在Linux系统中,SecureRandom的实现借助了/dev/random和/dev/urandom,可以使用硬件噪音生成随机数;

java random 伪随机_真/伪随机、以及随机算法相关推荐

  1. java伪协议_通过伪协议解决父页面与iframe页面通信的问题

    我们经常会有父页面与iframe页面的操作,比如 这个iframe里面的内容是js写的.如以下代码 var iframe = document.getElementById("iframe& ...

  2. java 缓存行填充_缓存伪共享问题以及解决方案缓存行填充

    缓存伪共享 共享对象存在同一个缓存中,由于MESI协议,一个对象中一些不需要改变的属性因为其他改变的属性,导致整个对象的缓存进入到M被修改状态. 目前的CPU是通常按照32或者64字节的缓存行(Cac ...

  3. vue移除伪元素_获取伪元素的属性和改变伪元素的属性

    获取伪元素的属性值 获取伪元素的属性值可以使用window.getComputedStyle()方法,获取伪元素的CSS样式声明对象.然后利用getPropertyValue方法或直接使用键值访问都可 ...

  4. python颜色填充随机_使用python中的随机数据填充mysql表

    How can create a mysql table in python and then populate it with random data.I want around 10000 row ...

  5. Java并发编程实战_真香!阿里P8耗时半年著作660页Java高并发与网络编程实战总结...

    随着软件行业的飞速发展,互联网公司对开发者的技能要求也越来越高.而高并发.网络编程.微服务.海量数据的处理等技能,是每一个开发者进阶时的必学知识.为了帮助初级开发者快速掌握这些实用技术,本书以&quo ...

  6. java 二维卡尔曼滤波_卡尔曼滤波(Kalman filtering)算法学习小记

    动画和视频 一个例子 import numpy as np # 模拟数据 t = np.linspace(1, 100, 100) a = 0.5 position = (a * t ** 2) / ...

  7. java实现频繁集_数据挖掘--频繁集测试--Apriori算法--java实现

    [ 关联规则挖掘用于寻找给定数据集中项之间的有趣的关联或相关关系. 关联规则揭示了数据项间的未知的依赖关系,根据所挖掘的关联关系,可以从� ...] 2013年11月19日注:以下算法中,combin ...

  8. java短链接原理_微博短链接的生成算法(Java版本)

    最近看到微博的短链接真是很火啊,新浪.腾讯.搜狐等微博网站都加入了短链接的功能.之所以要是使用短链接,主要是因为微博只允许发140 字,如果链接地址太长的话,那么发送的字数将大大减少.短链接的主要职责 ...

  9. java bresenham画直线_图形学笔记: Bresenham画线算法

    图形学课本, 按规矩介绍完矩阵行列式, 第一个算法肯定就是Bresenham画线算法了. 來我们來看看算法 Bresenham是用来画一些不反走样的线段的. 都说了线段肯定有起点和终点, 假设我们: ...

最新文章

  1. 多快好省的宏基因组研究技巧 — 资深专家分享
  2. 2021年春季学期-信号与系统-第十四次作业参考答案-第二小题参考答案
  3. C语言再学习 -- 三字母词(转)
  4. angularjs 导出excel php,AngularJS 导出Excel指令
  5. linux网络保存退出,linux编辑文件后如何保存退出
  6. linux手动同步文件命令,Linux文件同步命令rsync详解
  7. docker之使用supervisor管理多个进程
  8. 7 SDImageCache
  9. ffmpeg 封面提取
  10. java json 修改字段_我们如何使用Java中的Jackson来更改JSON中的字段名称?
  11. [导入]构建WCF面向服务的应用程序系列课程(10):安全基础.zip(24.27 MB)
  12. LC.234.Palindrome Linked List
  13. 【WinForm】自己写一个截图软件1 --注册全局热键
  14. 一刀工具箱 - 图片转链接(图床)工具
  15. 对一段Oracle GoldenGate (OGG) 传输进程日志(.rpt文件)的解释
  16. bomb和mysql,Bmob
  17. 客户数据平台(CDP)是什么?
  18. 解决git push 中remote: Permission to xxxxx.git denied to xxx. fatal: unable to acce
  19. 表情识别(七)--面部表情识别阶段综述(2018.4)
  20. php 数字 字母组合,PHP生成数字字母组合或纯数字的唯一订单号

热门文章

  1. 看到一个有意思的代码网页!!!!泡妹子的代码!!!
  2. 0014__格式化工厂(视频编辑软件包括去掉声音、添加字幕)
  3. Matlab灰度图像反转,对数变换,幂次变换
  4. JAVA 好书推荐整理
  5. 如何启动netcat_Netcat基础
  6. matlab 422,实现matlab YCbCr444转YCbCr422实例
  7. wireshark怎么抓apk 包_图解如何抓取手机的数据封包「手机抓包技术详解」
  8. 基于FPGA的学校打铃器(VHDL)
  9. html语言搭建网站,网络编程(1)——使用HTML搭建一个网页
  10. java用递归将数字转换字符串_用递归法将一个整数n转换成字符串,例如输入483,应该输出字符串483,n的位数不确定。...