Windows系统下快速生成随机数的技巧
日常工作中,需要使用随机数的场合很多。做实验时,可能需要一些随机数来作测试;不少产品商家需要给产品配上随机序列号,或给VIP用户卡分配随机卡号。那么,在Windows环境下,如何才能自动生成满足需要的随机数呢?
1. 特定区间普通随机数的生成
如果在进行实验时,需要生成一个特定区间内的随机数,首先可以通过我们所熟悉的Excel软件来创建。主要利用RAND和RANDBETWEEN两个函数来实现。
例如,需要生成0到1区间内的随机数,可使用函数“=RAND()”来实现;要生成0到10之间的随机数,可使用函数表达式“=RAND()*10”;若需要1到10之间的随机数,要用表达式“RAND()*(10-1)+1”。同样地,若需要0到100之间的随机数,使用“RAND()*100”函数表达式;1到100之间的随机数,使用“RAND()*(100-1)+2”函数表达式(图1)。
我们注意到,上述随机数都是小数。那么,如果要生成整数怎么办呢?有两种办法,一个是对生成的小数随机数取整,一个是直接生成整数随机数。第一种例如在表达式“RAND()*(100-1)+2”的基础上外加TRUNC()函数,生成1到100之间的随机整数,整个表达式表述为“=TRUNC(RAND()*(100-1)+2)”;第二种则可以直接使用RANDBETWEEN()函数,用表达式“=RANDBETWEEN(0,10)”生成0到10之间的随机整数,表达式“=RANDBETWEEN(50,9999)”生成50到9999之间的随机整数(图2)。可见,RANDBETWEEN()函数用起来更形象,也更简单。
如果觉得上述方式生成区间随机数比较麻烦,可利用第三方工具软件实现。比如使用Random Number Generator,可以很方便地进行随机数区域设置和条件限定,从而自动生成满足条件的随机数。
软件运行后,在左侧上方Interval from后的两个框中输入随机数生成的范围值,在Digits after decimal point后输入截取的小数位,在Number of digits to generate后输入每次生成的随机数个数。之后,点击Generate integer按钮即可生成指定数量的随机整数,点击Generate decimal则生成相应的随机小数(图3)。
随机数的生成条件设置之后,建立随机数的操作还可以用快捷键来完成。按下功能键F1可以建立指定范围的整数,按下F2生成指定范围的小数,按下F4则清除随机数列表。如果要生成大量的随机数,要从中找到一个特定的随机数是否存在,可使用Find按钮进行查找,找到后自动定位到该随机数(图4)。若中途要停止随机数的生成,可按下Esc键。
小提示:如果要求生成不重复的随机数,请选择Next random number does not equal current复选框。如果要复制生成的某个随机数或随机数列表,用软件窗口左下角的几个按钮来操作即可。
2. 特定格式产品序列号的生成
作为产品生产商家的工作人员,要给自己的软硬件产品编排序列号,或者销售商要给客户VIP卡配置序列号,也可以用两种方法来实现。
首先,可以使用Excel的随机函数表达式。假设要生成形如“123-456”这样的由两段三位数字和连字符组成随机数序列号,可以使用“=RANDBETWEEN(100,999)& " - " &RANDBETWEEN(100,999)”函数表达式。其中的“&”符号连接前后结果,而“-”表示以指定连字符连接前后两段随机数。
依此类推,如果要生成由四段六位数字组成的随机序列号,可使用“=RANDBETWEEN(100000,999999)& " - " &RANDBETWEEN(100000,999999)& " - " && " - " &RANDBETWEEN(100000,999999)& " - " &RANDBETWEEN(100000,999999)& " - " &RANDBETWEEN(100000,999999)& " - " &RANDBETWEEN(100000,999999)”函数表达式(图5)。
序列号的生成还可以使用第三方专用工具,如Portable Abluescarab Software CD-Key Generator软件。首次使用该软件弹出提示,需要进行参数配置,配置参数主要有序列号的段数和每段的字符数两个参数(图6)。
进入序列号生成器的主窗口后,先通过下拉列表,在使用数字、字符、数字+字符3种方式中选择一种,再通过下面的复选框选择是否使用小写字母,然后点击Generate按钮,即可建立一组序列号(图7)。
小提示:虽然该软件为CD-Key而设计,但生成其他产品序列号同样适用。
[!--empirenews.page--]
相关阅读:
一、c语言中的算法采用线性同余算法产生,首先要设置seed(),线性同余算法的随机性很差,不能满足加密的要求
二、windows下随机数的生成:
有两种方法可以生产随机数,包括:线性适配随机发生器和不可预测随机数发生器。
线性适配随机发生器:
在许多程序设计中,都简单地调用了相关的随机函数。比如windows下Microsoft Visual C++6.0 中的 rand(),在C 运行库(C Run Time lib,CRT)中,其定义类似如下(为了简洁起见,n省略了多线程程序部分等)。
int holdrand=1;
int _cdecl rand(void)
{ return ((holdrand=holdrand*214013L+25310112)>>16)&0x7fff}; }
该类型的函数被称为线性适配函数(linear congruential function)。 此类函数的一个的缺点就是可预测性,因为上一个随机数是下个随机数的种子,具有很强的相关性。其中两次与之相关的重要事件有:
① Netscape Navigator浏览器早期版本的攻击可能是最著名的可预测随机攻击,其中用于其SSL(Secure Sockets Layer,安全套接字层)密钥的随机数有着很高的可预测性,使得SSL 失去意义。
② 另一个就是攻击ASF软件公司的TexasHoldem Poker应用程序。这种“发牌”软件在算法中利用了Borland Delphi的随机函数。这个随机函数是类似于上面提及的CRT中的简单线性适配函数:rand()函数。
2. 不可预测随机数发生器
2.1 随机数发生器特性
一个好(或称健壮)的随机数发生器有着一下以下三个特性: ① 产生平均的数; ② 数据不可预测; ③ 取值范围长且完整(即:它能产生大量的不同值的随机数,而且在取值范围内的所有数值能够被生成)。
线性适配函数产生的随机数,仅满足第一个特性,第二个特性非常糟糕。换言之,rand()
函数可以生成一系列平均分布的数,但每一个数却有很强的可预测性。
2.2 不可预测随机发生器设计
在Windows环境中,一个健壮的随机函数是:CryptGenRandom()。它适用于Windows XP, Windows 2000 Professional, Windows NT Workstation 4.0, Windows Me, Windows 98, or Windows 95 OSR2 或更高版本,Windows Server 2003, Windows 2000 Server, or Windows NT Server 4.0及 Internet Explorer 3.02 or later on Windows 95,定义在Wincrypt.h.
CryptGenRandom从Windows2000的众多的资源中,获得其随机性[也称作“熵”(entropy)]:①当前进程的ID;②当前线程的ID;③系统引导以来的时钟数;④各种高精度的性能计数器;⑤用户环境模块的MD4(Message Digest 4,信息摘要4)散列,包括用户名,计算机名和搜索路径等;⑥高精度的内部CPU计算器,如RDISC,ROMSR,RDPM等;⑦底层系统信息,如空闲时间,内检时刻,中断时间,提交限定,页面计数,缓存计数,操作系统外部计数等。
(1) CryptGenRandom()函数的一般使用
①首先通过CryptAcquireContext 获取一个CSP (cryptographic service provider)提供的句柄,定义如下:
BOOL WINAPI CryptAcquireContext(
HCRYPTPROV* phProv,
LPCTSTR pszContainer,
LPCTSTR pszProvider,
DWORD dwProvType,
DWORD dwFlags
)
参数说明:
phProv : 一个密码的服务提供者(cryptographic service provider,CSP)的句柄指针。
PszContainer:关键字容器的名字。当 dwFlags 被设为 CRYPT_VERIFYCONTEXT 时, pszContainer 必须被设为 0。一般 pszContainer 为NULL时,一个缺省钥匙容器名字被使用。例如,微软基本密码提供者(Microsoft Base Cryptographic Provider)的用户使用其当前登录名字当前作为关键字容器名字登录。
PszProvider::指定的CSP提供者的名字,是以0结尾的字符串。如果这个参数是空的,用户缺省供应商被使用。
DwProvType:指定CSP提供者的类型,取值可如下。
PROV_RSA_FULL PROV_SSL
PROV_RSA_SIG PROV_EC_ECDSA_SIG
PROV_DSS PROV_EC_ECNRA_SIG
PROV_DSS_DH PROV_EC_ECDSA_FULL
PROV_FORTEZZA PROV_EC_ECNRA_FULL
PROV_MS_EXCHANGE PROV_SPYRUS_LYNKS
PROV_RSA_SCHANNEL
其中,PROV_RSA_FULL 标识,表示提供者同时支持数字签名(Digital signatures)和数据加密(Data encryption),为通用的一般的设置(其他的具体含义,可参看MSDN)。
DwFlags: 标志值。这个参数通常被设为零。 但是应用程序也可以设置至少一个下列标志: CRYPT_VERIFYCONTEXT,CRYPT_NEWKEYSET,CRYPT_MACHINE_KEYSET,CRYPT_DELETEKEYSET(其具体含义,可参看MSDN)。
返回值:如果函数调用成功,返回值是非零 (TRUE );反之,为0(FALSE)。
②调用CryptGenRandom()函数,同时将产生的随机数据填充到缓存区中。
BOOL WINAPI CryptGenRandom(
HCRYPTPROV hProv,
DWORD dwLen,
BYTE* pbBuffer
);
参数说明:
hProv :是一个由CSP(cryptographic service provider)句柄,它由CryptAcquireContext函数调用获得的。
dwLen :缓存区的大小。
pbBuffer :存放返回随机数据的缓存区。
返回值:
调用成功则返回 TRUE;反之为FALSE。
③使用完毕释放句柄和关键字容器:CryptReleaseContext()。
调用CryptReleaseContext将释放一个CSP 句柄;同时,每调用一次,引用计数(Reference count)将减1,当引用计数为零时,则CSP上下文(context)将被彻底释放,不再能被其他应用所使用。其定义如下:
BOOL WINAPI CryptReleaseContext(
HCRYPTPROV hProv,
DWORD dwFlags
);
参数说明:
hProv :欲释放的一个CSP 句柄
dwFlags :保留使用,一般设为0。
返回值:调用成功则返回非零(TRUE)。