吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2797|回复: 0
收起左侧

[其他原创] 正确生成随机数的两种姿势

[复制链接]
pcy190 发表于 2019-2-21 17:52
本帖最后由 pcy190 于 2019-2-21 17:59 编辑

第一次发帖,还请大佬们轻拍。

为什么不推荐用rand()函数,可以看看https://codeforces.com/blog/entry/61587。

使用RDSEEDRDRAND指令

RDSEED,RDRAND是两个汇编指令,通过硅片上的热噪声来生成随机数。

  • 从Intel Broadwell架构的 CPU 和AMD Zen架构的 CPU开始支持此指令

  • 在AMD和Intel的CPU上,可以使用CPUID指令来检测CPU是否支持RDRAND指令。如果支持该指令,调用CPUID的01号标准函数之后,ECX寄存器的第30位会被设置成1。

  • 从RDSEED指令获取输入流比从RDRAND获取要慢。

关于RDSEED和RDRAND指令的区别和具体工作,文献很少。笔者从INTEL官网找到了相关文章。

大意就是如果打算用来作为其它伪随机数生成器(pseudorandom number generator)的种子的时候,可以使用RDSEED,其他情况则使用RNRAND

感兴趣的读者可以戳此https://software.intel.com/en-us/blogs/2012/11/17/the-difference-between-rdrand-and-rdseed

首先检测当前CPU是否支持RDRAND,我们通过调用CPUID的01号标准函数,根据执行后的ECX寄存器第30位是否为1来判断。如果为1,则支持。

cpuid
and eax, 0x20000000 //比较第30位
test eax, 0

核心代码就是rdrand eax将生成的随机数放到eax寄存器中

下面是自己写的生成100个随机数生成的代码,仅供参考。

#include <iostream>
using namespace std;
int main()
{
        bool flag = 0;
        unsigned int result = 0;
        __asm {
                mov eax, 1
                cpuid
                and eax, 0x20000000 //30th bit
                test eax, 0
                jnz L
                mov flag, 1
                L:
        }
        if (!flag) {
                cout << "Not support this CPU!";
                return 0;
        }
        for (int i = 0; i < 100; i++) {
                __asm {
                        rdrand eax
                        mov result, eax
                }
                cout << result << endl;
        }
        return 0;
}

使用mt19937

mt19937是什么?它是c++11中加入的新特性,是一种随机数算法。

总的一点,相对于传统的srand(),mt19937拥有更好的性能。

具有速度快,周期长的特点(它的名字便来自周期长度:2^19937-1)

rand()函数在windows下生成的数据范围为0-32767

但是这个mt19937的随机范围在(−MAXINT,+MAXINT)   (其中MAXINT为int的最大值)

它的使用非常简单

#include<random>
#include<ctime>
std::mt19937 rnd (time(0));
int main()
{
    printf("%lld\n",rnd());
    return 0;
}

另外,random_shuffle使用的时自带的rand()

我们可以把rnd函数传入shuffle,使shuffle更随机

shuffle(a, a + n, rnd); //a为数组

这样就能让数组内的元素随机移动足够大的距离

关于mt19937具体可以见std::mt19937

总体来说,mt19937使用很方便,RDRAND作为CPU层面的随机数,具有更佳的表现。

[/md]

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-5-17 08:53

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表