热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

两种方法生成安全的随机数(置顶)

在许多类型软件的开发过程中,都要使用随机数。例如纸牌的分发、密钥的生成等等。随机数至少应该具备两个条件:1.数字序列在统计上是随机的。2.不能通过已知序

在许多类型软件的开发过程中,都要使用随机数。例如纸牌的分发、密钥的生成等等。随机数至少应该具备两个条件:

1. 数字序列在统计上是随机的。
2. 不能通过已知序列来推算后面未知的序列。

只有实际物理过程才是真正随机的。而一般来说,计算机是很确定的,它很难得到真正的随机数。所以计算机利用设计好的一套算法,再由用户提供一个种子值,得出被称为“伪随机数”的数字序列,这就是我们平时所使用的随机数。

这种伪随机数字足以满足一般的应用,但它不适用于加密等领域,因为它具有弱点:

1. 伪随机数是周期性的,当它们足够多时,会重复数字序列。
2. 如果提供相同的算法和相同的种子值,将会得出完全一样的随机数序列。
3. 可以使用逆向工程,猜测算法与种子值,以便推算后面所有的随机数列。

即是说:

随机序列 = F(算法, 种子)

 

一、System.Random类

System.Random类是最常用的伪随机数生成器,我们经常使用它创建近似随机的数列。以下代码演示了Random类创建10个随机数:

Random random = new Random();
for (int i &#61; 0; i < 10; i&#43;&#43;)
    Console.WriteLine(random.Next());

在创建Rondom类的实例时&#xff0c;我们可以指定Int32类型的种子值&#xff0c;不指定默认用Environment.TickCount作种子&#xff0c;它是从系统启动到现在经过的毫秒数。然后使用Next()方法来获得Int32类型的随机数值。Next()方法有3个重载&#xff0c;可以实现获得指定范围内的随机数值。

使用Rondom类时最常见的错误&#xff0c;是将创建Random实例的语句放在一个路径很短的循环中。如&#xff1a;

for (int i &#61; 0; i < 10; i&#43;&#43;)
ExpandedBlockStart.gifContractedBlock.gif
{
    Random random_A 
&#61; new Random();
    
sbyte randomNumber &#61; (sbyte)(random_A.Next(0101));
    Console.WriteLine(randomNumber);
}

根据现在的计算机运行速度&#xff0c;执行这段代码根本用不了多少时间。所以在10次循环中&#xff0c;构造函数使用的Environment.TickCount几乎一样。随机数不随机的结果。

每次都是随机产生的.我又按F9,F10进行调试检查&#xff0c;让程序一步一步的运行&#xff0c;让随机数一个一个的产生,这时我就发现每次产生的随机数几乎都不一样

这个错误也验证了伪随机数的弱点。我们都用Random类&#xff0c;算法是一样的&#xff0c;所以一旦得知了程序使用的种子&#xff0c;那么程序过程就变得十分确定了。

 

二、RNGCryptoServiceProvider类

为了获得更加随机的数字序列&#xff0c;可以使用System.Security.Cryptography.RNGCryptoServiceProvider类。它使用加密服务提供程序 (CSP) 提供的实现来实现加密随机数生成器。

下面代码演示了RNGCryptoServiceProvider类创建10个随机数

byte[] bytes &#61; new byte[4];
RNGCryptoServiceProvider r 
&#61; new RNGCryptoServiceProvider();

for (int i &#61; 0; i < 10; i&#43;&#43;)
ExpandedBlockStart.gifContractedBlock.gif
{
    r.GetBytes(bytes);
    
int number &#61; BitConverter.ToInt32(bytes, 0);
    Console.WriteLine(number);
}

RNGCryptoServiceProvider类产生的随机数更加随机。即使有人知道了这个类&#xff0c;并得到最近生成的随机序列&#xff0c;也无法计算后续序列。

目前RNGCryptoServiceProvider类并没有提供获取指定范围的随机数的方法&#xff0c;需要自己处理。下面代码演示了创建从1到100的10个随机数&#xff1a;

byte[] bytes &#61; new byte[16];
RNGCryptoServiceProvider r 
&#61; new RNGCryptoServiceProvider();

for (int i &#61; 0; i < 10; i&#43;&#43;)
ExpandedBlockStart.gifContractedBlock.gif
{
    r.GetBytes(bytes);
    
int number &#61; (int)((decimal)bytes[0/ 256 * 100&#43; 1;
    Console.WriteLine(number);
}

最后测试了一下&#xff0c;将RNGCryptoServiceProvider类对象的创建放在循环中&#xff0c;仍然能获得随机数&#xff1a;

byte[] bytes &#61; new byte[4];

for (int i &#61; 0; i < 10; i&#43;&#43;)
ExpandedBlockStart.gifContractedBlock.gif
{
    RNGCryptoServiceProvider r 
&#61; new RNGCryptoServiceProvider();
    r.GetBytes(bytes);
    
int number &#61; BitConverter.ToInt32(bytes, 0);
    Console.WriteLine(number);
}

当然&#xff0c;不推荐这么去写&#xff0c;毕竟对象的创建也是很费时间的。

最后说明一点&#xff0c;RNGCryptoServiceProvider类要比Random类耗费更多的时间&#xff0c;若打算在很短时间内生成大量随机数&#xff0c;请不要使用RNGCryptoServiceProvider类。

[视频]Visual Studio 2005入门之对象概述

[视频]Visual Studio 2005入门之创建对象和使用方法以及属性

[视频]Visual Studio 2005入门之利用构造函数初始化对象

[视频]Visual Studio 2005入门之重载方法以及运算符重载

[视频]Visual Studio 2005入门之.Net核心对象(Request)

...

转:https://www.cnblogs.com/fhbcn/archive/2009/01/15/1376670.html



推荐阅读
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • WebSocket与Socket.io的理解
    WebSocketprotocol是HTML5一种新的协议。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送 ... [详细]
  • macOS Big Sur全新设计大版本更新,10+个值得关注的新功能
    本文介绍了Apple发布的新一代操作系统macOS Big Sur,该系统采用全新的界面设计,包括图标、应用界面、程序坞和菜单栏等方面的变化。新系统还增加了通知中心、桌面小组件、强化的Safari浏览器以及隐私保护等多项功能。文章指出,macOS Big Sur的设计与iPadOS越来越接近,结合了去年iPadOS对鼠标的完善等功能。 ... [详细]
  • 超级简单加解密工具的方案和功能
    本文介绍了一个超级简单的加解密工具的方案和功能。该工具可以读取文件头,并根据特定长度进行加密,加密后将加密部分写入源文件。同时,该工具也支持解密操作。加密和解密过程是可逆的。本文还提到了一些相关的功能和使用方法,并给出了Python代码示例。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 深入理解Kafka服务端请求队列中请求的处理
    本文深入分析了Kafka服务端请求队列中请求的处理过程,详细介绍了请求的封装和放入请求队列的过程,以及处理请求的线程池的创建和容量设置。通过场景分析、图示说明和源码分析,帮助读者更好地理解Kafka服务端的工作原理。 ... [详细]
  • Win10 64位旗舰版的优势及特点详解
    本文详细介绍了Win10 64位旗舰版的优势及特点,包括更安全的源安装盘、永久激活方式、稳定性和硬件驱动的集成,以及人性化的维护工具和分区功能。通过阅读本文,您将了解到Win10 64位旗舰版相比其他版本的优势和特点。 ... [详细]
  • 集成电路企业在进行跨隔离网数据交换时面临着安全性问题,传统的数据交换方式存在安全性堪忧、效率低下等问题。本文以《Ftrans跨网文件安全交换系统》为例,介绍了如何通过丰富的审批流程来满足企业的合规要求,保障数据交换的安全性。 ... [详细]
  • Java SE从入门到放弃(三)的逻辑运算符详解
    本文详细介绍了Java SE中的逻辑运算符,包括逻辑运算符的操作和运算结果,以及与运算符的不同之处。通过代码演示,展示了逻辑运算符的使用方法和注意事项。文章以Java SE从入门到放弃(三)为背景,对逻辑运算符进行了深入的解析。 ... [详细]
  • GreenDAO快速入门
    前言之前在自己做项目的时候,用到了GreenDAO数据库,其实对于数据库辅助工具库从OrmLite,到litePal再到GreenDAO,总是在不停的切换,但是没有真正去了解他们的 ... [详细]
  • 恶意软件分析的最佳编程语言及其应用
    本文介绍了学习恶意软件分析和逆向工程领域时最适合的编程语言,并重点讨论了Python的优点。Python是一种解释型、多用途的语言,具有可读性高、可快速开发、易于学习的特点。作者分享了在本地恶意软件分析中使用Python的经验,包括快速复制恶意软件组件以更好地理解其工作。此外,作者还提到了Python的跨平台优势,使得在不同操作系统上运行代码变得更加方便。 ... [详细]
author-avatar
刘浩不来丷上海594865126
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有