API篇(Java - 随机器(Random))(doing)

news2024/11/27 5:21:09

目录

一、Random

1. 简介

2. 什么是种子

3. 相关方法

4. Random对象的生成

5. Random类中的常用方法

6. 使用

6.1. 创建对象

6.2. 生成[0,1.0)区间的小数

6.3. 生成[0,5.0)区间的小数

6.4. 生成[1,2.5)区间的小数

6.5. 生成任意整数

6.6. 生成[0,10)区间的整数

6.7. 生成任意[0,n)区间的随机整数

6.8. 生成[0,10]区间的整数

6.9. 生成[-3,15)区间的整数

6.10. 几率实现

7. 其它问题

7.1. 相同种子数Random对象问题

7.2. 关于Math类中的random方法

8. 演示案例

8.1. 产生随机数

8.2. 猜数字

二、SecureRandom

1. 概述

2. Random vs SecureRandom

3. 使用

3.1. 使用java.util.Random生成随机数

3.2. 使用java.security.SecureRandom生成随机数


一、Random

1. 简介

java Random类位于java.util包下,主要用来生成随机数。

Random类中实现的随机算法是伪随机,也就是有规则的随机。

在进行随机时,随机算法的起源数字称为种子数(seed),在种子数的基础上进行一定的变换,从而产生需要的随机

数字。

相同种子数的Random对象,相同次数生成的随机数字是完全相同的。

也就是说,两个种子数相同的Random对象,第一次生成的随机数字完全相同,第二次生成的随机数字也完全相

同。这点在生成多个随机数字时需要特别注意。

2. 什么是种子

种子就是一个用于初始化一个随机数字生成器的数字,无参构造方法使用当前已经逝去的时间作为种子,创建一

个Random对象。

如果两个Random对象有相同的种子,就会产生相同的数列!

创建一个Random对象的时候,必须指定一个种子或者使用默认的种子。

3. 相关方法

4. Random对象的生成

Random类包含两个构造方法,下面依次进行介绍:

public Random():该构造方法使用一个和当前系统时间对应的相对时间有关的数字作为种子数,然后使用这个种子数构造Random对象。
public Random(long seed):该构造方法可以通过制定一个种子数进行创建。

演示:

Random r = new Random();
Random r1 = new Random(10);

再次强调:种子数只是随机算法的起源数字,和生成的随机数字的区间无关。

5. Random类中的常用方法

Random类中的方法比较简单,每个方法的功能也很容易理解。

需要说明的是,Random类中各方法生成的随机数字都是均匀分布的,也就是说区间内部的数字生成的几率是均

等的。下面对这些方法做一下基本的介绍:

public boolean nextBoolean():该方法的作用是生成一个随机的boolean值,生成true和false的值几率相等,也就是都是50%的几率。

public double nextDouble():该方法的作用是生成一个随机的double值,数值介于[0,1.0)之间。

public int nextInt():该方法的作用是生成一个随机的int值,该值介于int的区间,也就是-231到231-1之间。

public int nextInt(int n):该方法的作用是生成一个随机的int值,该值介于[0,n)的区间,也就是0到n之间的随机int值,包含0而不包含n。

public void setSeed(long seed):该方法的作用是重新设置Random对象中的种子数。设置完种子数以后的Random对象和相同种子数使用new关键字创建出的Random对象相同。

6. 使用

使用Random类,一般是生成指定区间的随机数字,下面就一一介绍如何生成对应区间的随机数字。

6.1. 创建对象

Random r = new Random();

6.2. 生成[0,1.0)区间的小数

double d1 = r.nextDouble();

直接使用nextDouble方法获得。

6.3. 生成[0,5.0)区间的小数

double d2 = r.nextDouble() * 5;

因为nextDouble方法生成的数字区间是[0,1.0),将该区间扩大5倍即是要求的区间。

同理,生成[0,d)区间的随机小数,d为任意正的小数,则只需要将nextDouble方法的返回值乘以d即可。

6.4. 生成[1,2.5)区间的小数

double d3 = r.nextDouble() * 1.5 + 1;

生成[1,2.5)区间的随机小数,则只需要首先生成[0,1.5)区间的随机数字,然后将生成的随机数区间加1即可。

同理,生成任意非从0开始的小数区间[d1,d2)范围的随机数字(其中d1不等于0),

则只需要首先生成[0,d2-d1)区间的随机数字,然后将生成的随机数字区间加上d1即可。

6.5. 生成任意整数

int n1 = r.nextInt();

直接使用nextInt方法即可

6.6. 生成[0,10)区间的整数

int n2 = r.nextInt(10);
n2 = Math.abs(r.nextInt() % 10);

以上两行代码均可生成[0,10)区间的整数。

第一种实现使用Random类中的nextInt(int n)方法直接实现。

第二种实现中,首先调用nextInt()方法生成一个任意的int数字,

该数字和10取余以后生成的数字区间为(-10,10),然后再对该区间求绝对值,则得到的区间就是[0,10)了。

6.7. 生成任意[0,n)区间的随机整数

int n2 = r.nextInt(n);
n2 = Math.abs(r.nextInt() % n);

6.8. 生成[0,10]区间的整数

int n3 = r.nextInt(11);
n3 = Math.abs(r.nextInt() % 11);

相对于整数区间,[0,10]区间和[0,11)区间等价,所以即生成[0,11)区间的整数。

6.9. 生成[-3,15)区间的整数

int n4 = r.nextInt(18) - 3;
n4 = Math.abs(r.nextInt() % 18) - 3;

生成非从0开始区间的随机整数,可以参看上面非从0开始的小数区间实现原理的说明。

6.10. 几率实现

按照一定的几率实现程序逻辑也是随机处理可以解决的一个问题。

下面以一个简单的示例演示如何使用随机数字实现几率的逻辑。

在前面的方法介绍中,nextInt(int  n)方法中生成的数字是均匀的,也就是说该区间内部的每个数字生成的几率是

相同的。

那么如果生成一个[0,100)区间的随机整数,则每个数字生成的几率应该是相同的,而且由于该区间中总计有100

个整数,所以每个数字的几率都是1%。

按照这个理论,可以实现程序中的几率问题。

示例:随机生成一个整数,该整数以55%的几率生成1,以40%的几率生成2,以5%的几率生成3。

代码如下:

int n5 = r.nextInt(100);
int m; //结果数字
if(n5 < 55){ //55个数字的区间,55%的几率
    m = 1;
}else if(n5 < 95){//[55,95),40个数字的区间,40%的几率
    m = 2;
}else{
    m = 3;
}

因为每个数字的几率都是1%,则任意55个数字的区间的几率就是55%,

为了代码方便书写,这里使用[0,55)区间的所有整数,后续的原理一样。

当然,这里的代码可以简化,因为几率都是5%的倍数,所以只要以5%为基础来控制几率即可,下面是简化的代码

实现:

int n6 = r.nextInt(20);
int m1;
if(n6 < 11){
    m1 = 1;
}else if(n6 < 19){
    m1 = 2;
}else{
    m1 = 3;
}

在程序内部,几率的逻辑就可以按照上面的说明进行实现。

7. 其它问题

7.1. 相同种子数Random对象问题

前面介绍过,相同种子数的Random对象,相同次数生成的随机数字是完全相同的,下面是测试的代码:

代码如下:

Random r1 = new Random(10);
Random r2 = new Random(10);
for(int i = 0;i < 2;i++){
     System.out.println(r1.nextInt());
     System.out.println(r2.nextInt());
}

在该代码中,对象r1和r2使用的种子数都是10,则这两个对象相同次数生成的随机数是完全相同的。

如果想避免出现随机数字相同的情况,则需要注意,无论项目中需要生成多少个随机数字,都只使用一个、

Random对象即可。

7.2. 关于Math类中的random方法

其实在Math类中也有一个random方法,该random方法的工作是生成一个[0,1.0)区间的随机小数。

通过阅读Math类的源代码可以发现,Math类中的random方法就是直接调用Random类中的nextDouble方法实

现的。只是random方法的调用比较简单,所以很多程序员都习惯使用Math类的random方法来生成随机数字。

8. 演示案例

8.1. 产生随机数

package com.zheng.d2_random;
import java.util.Random;
/*
	Random

	作用:
		用于产生一个随机数

	使用步骤:
		1:导包
			import java.util.Random;
		2:创建对象
			Random r = new Random();
		3:获取随机数
			int number = r.nextInt(10);
			获取数据的范围:[0,10) 包括0,不包括10
*/


public class RandomDemo {
	public static void main(String[] args) {
		//创建对象
		Random r = new Random();

		//用循环获取10个随机数
		for(int i=0; i<10; i++) {
			//获取随机数
			int number = r.nextInt(10);
			System.out.println("number:" + number);
		}

		//需求:获取一个1-100之间的随机数
		int x = r.nextInt(100) + 1;
		System.out.println(x);
	}
}

8.2. 猜数字

package com.zheng.d2_random;
import java.util.Random;
import java.util.Scanner;

/*
	猜数字

	需求:
		程序自动生成一个1-100之间的数字,使用程序实现猜出这个数字是多少?
		当猜错的时候根据不同情况给出相应的提示

		如果猜的数字比真实数字大,提示你猜的数据大了
		如果猜的数字比真实数字小,提示你猜的数据小了
		如果猜的数字与真实数字相等,提示恭喜你猜中了
*/
public class RandomTest {
	public static void main(String[] args) {
		//要完成猜数字的游戏,首先需要有一个要猜的数字,使用随机数生成该数字,范围1到100
		Random r = new Random();
		int number = r.nextInt(100) + 1;

		while(true) {
			//使用程序实现猜数字,每次均要输入猜测的数字值,需要使用键盘录入实现
			Scanner sc = new Scanner(System.in);

			System.out.println("请输入你要猜的数字:");
			int guessNumber = sc.nextInt();

			//比较输入的数字和系统产生的数据,需要使用分支语句。这里使用if..else..if..格式,根据不同情况进行猜测结果显示
			if(guessNumber > number) {
				System.out.println("你猜的数字" + guessNumber + "大了");
			} else if(guessNumber < number) {
				System.out.println("你猜的数字" + guessNumber + "小了");
			} else {
				System.out.println("恭喜你猜中了");
				break;
			}
		}

	}
}

二、SecureRandom

1. 概述

java.security.SecureRandom类:该类提供了一个加密强随机数生成器(RNG)。加密强随机数最低限度地符合

FIPS  140-2(加密模块的安全要求,第4.9.1节)中规定的统计随机数生成器测试。此外,SecureRandom必须产生

不确定的输出。因此,传递给SecureRandom对象的任何种子材料必须是不可预测的,而且所有SecureRandom

输出序列必须具有强加密能力。

java.util.Random类:Random中定义的类在密码学上不是强的,选择的数字也不是完全随机的,因为使用了确定

的数学算法(基于Donald E. Knuth的减法随机数生成器算法)来选择它们。因此,对于需要较高安全性的任务(如创

建随机密码等)使用该类是不安全的。

2. Random vs SecureRandom

  1. 大小:一个Random类只有48位,而SecureRandom最多可以有128位。所以在SecureRandom中重复的机会较小。
  2. 种子生成:随机使用系统时钟作为种子/或生成种子。因此,如果攻击者知道种子产生的时间,它们就可以很容易地繁殖。但SecureRandom从您的OS中获取随机数据(它们可以是按键之间的间隔等-大多数OS收集这些数据并将它们存储在文件中- /dev/ Random和/dev/urandom在linux/solaris的情况下),并将其用作种子。
  3. 解码:在随机的情况下,只需要2^48次的尝试,在今天先进的cpu,它是有可能在实际时间打破它。但是为了安全起见,随机的2^128次尝试是必须的,这将花费许多年的时间,以今天的先进机器来实现收支平衡。
  4. 生成函数:标准的Oracle JDK 7实现使用所谓的线性同余生成器在java.util.Random中生成随机值。
    Secure  Random实现了SHA1PRNG算法,使用SHA1算法生成伪随机数。该算法在一个真正的随机数上计算SHA-1哈希值(使用一个熵源),然后将其与一个64位计数器连接,该计数器在每次操作中递增1。
  5. 安全性:因此,java.util。不能将随机类用于安全性关键的应用程序或保护敏感数据。

3. 使用

3.1. 使用java.util.Random生成随机数

// A Java program to demonstrate
// random number generation
// using java.util.Random;
import java.util.Random;
 
public class generateRandom {
 
    public static void main(String args[]){
        // create instance of Random class
        Random rand = new Random();
 
        // Generate random integers in range 0 to 999
        int rand_int1 = rand.nextInt(1000);
        int rand_int2 = rand.nextInt(1000);
 
        // Print random integers
        System.out.println("Random Integers: " + rand_int1);
        System.out.println("Random Integers: " + rand_int2);
    }
}

输出:

Random Integers: 956
Random Integers: 678

3.2. 使用java.security.SecureRandom生成随机数

// A Java program to demonstrate secure
// random number generation
// using java.security.SecureRandom
import java.security.SecureRandom;
 
public class generateRandom {
 
    public static void main(String args[]){
        // create instance of SecureRandom class
        SecureRandom rand = new SecureRandom();
 
        // Generate random integers in range 0 to 999
        int rand_int1 = rand.nextInt(1000);
        int rand_int2 = rand.nextInt(1000);
 
        // Print random integers
        System.out.println("Random Integers: " + rand_int1);
        System.out.println("Random Integers: " + rand_int2);
    }
}

输出:

Random Integers: 817
Random Integers: 500

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2062654.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LCP9回文数[leetcode-9-easy]

LCP&#xff0c;9回文数 给你一个整数 x &#xff0c;如果 x 是一个回文整数&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 回文数 是指正序&#xff08;从左向右&#xff09;和倒序&#xff08;从右向左&#xff09;读都是一样的整数。 例如&#xff…

Vue 3 的 emit 简单使用

在 Vue 3 中使用 emit&#xff0c;子组件可以将事件通知父组件&#xff0c;父组件可以在响应这些事件时执行特定的逻辑。 emit 是一种非常灵活的通信方式&#xff0c;允许组件之间以解耦的方式进行交互。 1. 基本用法 1、使用 defineEmits 子组件 <template><div…

【Hadoop】知识点总结、大学期末复习

博主简介&#xff1a;努力学习的22级计算机科学与技术本科生一枚&#x1f338;博主主页&#xff1a; Yaoyao2024往期回顾&#xff1a; 【论文精读】上交大、上海人工智能实验室等提出基于配准的少样本异常检测框架超详细解读&#xff08;翻译&#xff0b;精读&#xff09;每日一…

关于Hipe并发库中动态线程库DynamicThreadPond的一点解读(四)

文章目录 前提提交的任务有返回值怎么办总结 前提 上一节关于Hipe并发库中动态线程库DynamicThreadPond的一点解读(三)我们分析了以何种方式向线程池提交任务、提交的任务若有参数怎么办&#xff0c;这一节我们分析提交的任务若有返回值怎么办&#xff1f; 提交的任务有返回值…

bootloader相关内容的辨析

在PC机中&#xff0c;BIOS&#xff08;Basic Input/Output System&#xff0c;基本输入输出系统&#xff09;和UEFI&#xff08;Unified Extensible Firmware Interface&#xff0c;统一可扩展固件接口&#xff09;是两种用于初始化系统硬件、加载操作系统启动程&#xff08;如…

nestjs nest-cli.json中的assets不生效

官方文档 Documentation | NestJS - A progressive Node.js framework // nest-cli.json{"collection": "nestjs/schematics","sourceRoot": "src","compilerOptions": {"assets": ["microservices/mail/te…

【宠粉赠书】智能计算系统:从深度学习到大模型 第2版

为了回馈粉丝们的厚爱&#xff0c;今天小智给大家送上一套关于图神经网络的学习宝典——《智能计算系统&#xff1a;从深度学习到大模型 第2版》。下面我会详细给大家介绍这本书&#xff0c;文末留有领取方式。 “只要你想把大模型做得更好、做得更大、做得更快、做得更省电&am…

Docker部署常用开发组件(保姆级教程)

说明 本文总结了一些常用组件的Docker启动命令及过程&#xff0c;在开发过程中只需花费数分钟下载和配置即可完美使用这些服务。 Mysql MySQL 是一种开源关系数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;目前由 Oracle 公司维护。MySQL 以其高性能、可靠性和易用…

Qt4代码实现下面的界面

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

AI预测体彩排3采取888=3策略+和值012路或胆码测试8月22日升级新模型预测第59弹

经过近60期的测试&#xff0c;当然有很多彩友也一直在观察我每天发的预测结果&#xff0c;得到了一个非常有价值的信息&#xff0c;那就是9码定位的命中率非常高&#xff0c;已到达90%的命中率&#xff0c;这给喜欢打私菜的朋友提供了极高价值的预测结果~当然了&#xff0c;大部…

【C++】map、set基本用法

欢迎来到我的Blog&#xff0c;点击关注哦&#x1f495; 前言: C的STL已经学习很大一部分了&#xff0c;接下来介绍的是map set是c的是两种关联容器。 简单介绍 map set&#xff1a; 两者都使用红黑树作为底层数据结构来存储元素。map是一种键值对容器&#xff0c;其中每个键…

pip package查询网站(性质类似于npmjs.com)

网址&#xff1a;PyPI The Python Package Index python 的依赖包查询网站 就和 node 的 npmjs.com 一样

SD-WAN采用哪种网络技术?如何自建SD-WAN组网?

SD-WAN&#xff08;Software-Defined Wide Area Network&#xff0c;软件定义广域网&#xff09;是一种基于软件的网络架构&#xff0c;它利用软件定义网络&#xff08;SDN&#xff09;的技术来管理广域网&#xff08;WAN&#xff09;的连接和服务。SD-WAN的主要目的是提高网络…

四大LLM模型,预训练和后训练新范式详解

导读 最初&#xff0c;大语言模型LLM的训练过程只关注于预训练&#xff0c;但如今已经扩展到包含预训练和后训练两个阶段。后训练通常包括监督指令微调和对齐&#xff0c;这一方法在ChatGPT发布后广泛流行&#xff01; 翻译自:https://magazine.sebastianraschka.com/p/new-l…

基于距离度量学习的异常检测:一种通过相关距离度量的异常检测方法

异常通常被定义为数据集中与大多数其他项目非常不同的项目。或者说任何与所有其他记录(或几乎所有其他记录)显著不同的记录,并且与其他记录的差异程度超出正常范围,都可以合理地被认为是异常。 例如上图显示的数据集中,我们有四个簇(A、B、C和D)和三个位于这些簇之外的点:P1、P…

领夹麦克风哪个牌子的好,2024年无线领夹麦克风十大品牌推荐

在追求高质量音频的时代&#xff0c;一款性能稳定、音质出色的无线领夹麦克风&#xff0c;不仅能够提升内容创作的品质&#xff0c;也是赠予播客爱好者、视频博主的佳礼。然而&#xff0c;市场上的无线领夹麦克风品种繁多&#xff0c;其中不乏一些厂商为追求低成本&#xff0c;…

微软Phi-3.5系列亮相:性能超越Gemini 1.5和GPT-4o

前沿科技速递&#x1f680; 在人工智能领域&#xff0c;微软从未停止过创新的步伐。尽管与OpenAI的合作为微软带来了显著的成功&#xff0c;但他们显然不满足于此。近日&#xff0c;微软再次在AI领域引发关注&#xff0c;正式发布了三款全新的Phi-3.5系列AI模型。这些模型不仅在…

构建基于LLM的应用程序——使用LLM的搜索和推荐引擎

在上一章中&#xff0c;我们介绍了构建对话应用程序的核心步骤。我们从一个基础的聊天机器人开始&#xff0c;然后逐步添加了更复杂的组件&#xff0c;例如记忆、非参数化知识和外部工具。借助LangChain的预构建组件以及Streamlit的UI渲染&#xff0c;这一切都变得相对简单。尽…

C++ TinyWebServer项目总结(6. 高级 I/O 函数)

文件描述符 文件描述符&#xff08;File Descriptor, FD&#xff09;是操作系统中用于访问文件的一个抽象概念。它是一个非负整数&#xff0c;通常由操作系统分配&#xff0c;用来标识被打开的文件或输入输出资源&#xff08;如管道、网络连接等&#xff09;。文件描述符在操作…

苍穹外卖之员工管理、分类管理

新增员工 新增员工 需求分析和设计 产品原型&#xff1a; 接口设计&#xff1a; 数据库设计&#xff1a; 代码开发 根据新增员工接口设计对应的DTO&#xff1a; 这是实体类属性&#xff0c;但是由于属性差异过大&#xff0c;使用DTO封装数据为&#xff1a; 当前端提交的数据…