RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1059739
Accepted
David
David
Asked:2020-12-17 17:44:28 +0000 UTC2020-12-17 17:44:28 +0000 UTC 2020-12-17 17:44:28 +0000 UTC

生成大(64 位和 128 位)随机数

  • 772

如何实现大随机数的生成?

内置函数 rand 和 srand 最多只能生成 32000 个值。

我想产生高达数十亿的数字。

c++
  • 5 5 个回答
  • 10 Views

5 个回答

  • Voted
  1. Best Answer
    Harry
    2020-12-17T17:49:50Z2020-12-17T17:49:50Z

    仅有的?

    十亿很合适int。它将long long容纳数十亿 - 对于标准库来说,这是一个正常的全职工作......

    标准库<random>可以提供帮助。

    但是,即使您不想使用 C++ 11 标准,Knuth 也会为您提供帮助 - 这是我很久以前(当库只提供rand())根据 Knuth 编写的几个生成器(对不起,我不会重写算法,请参阅书籍):

    class Random
    {
    public:
        typedef int RandomValue;
        Random& operator = (int seed) { X = seed; return *this; }
        Random(int seed = 1):X(seed){};
        int operator()(int seed = 0)
        {
            const int MM = 2147483647;
            const int AA =      48271;
            const int QQ =      44488;
            const int RR =       3399;
            if (seed != 0) X = seed;
            X = AA*(X%QQ)-RR*(X/QQ);
            if (X < 0) X += MM;
            return X-1;
        }
        // Не включая max
        int operator()(int min, int max)
        {
            return (*this)()%(max-min) + min;
        }
    private:
        int X;
    };
    
    class Random64
    {
    typedef unsigned long long uint64;
    public:
        typedef uint64 RandomValue;
        Random64& operator = (uint64 seed) { X = seed; return *this; }
        Random64(uint64 seed = 0):X(seed){};
        uint64 operator()(uint64 seed = uint64(-1))
        {
            const uint64 a = 3202034522624059733ULL;
            const uint64 c =                   1ULL;
    
            if (seed != uint64(-1)) X = seed;
            uint64 Y = a * X + c;
            X = a * Y + c;
            Y = (Y&0xFFFFFFFF00000000ULL) | (X >> 32);
            return Y;
        }
        // Не включая max
        uint64 operator()(uint64 min, uint64 max)
        {
            return (*this)()%(max-min) + min;
        }
    private:
        uint64 X;
    };
    

    这是一个工作示例。

    • 6
  2. AnT stands with Russia
    2020-12-17T17:57:27Z2020-12-17T17:57:27Z

    如果您有一个现成的具有n位长度的数字生成器,那么您可以通过从对现有生成器的连续调用中获得的位序列的通常串联来从中获得更长数字的生成器。

    在您的问题中,您提到了一个生成 15 个伪随机位的生成器。对此类生成器的五次调用将为您提供一个 64 位伪随机数

    uint64_t rand64 = ((((((((uint64_t) rand() << 15) + rand()) << 15) + rand()) << 15) + rand()) << 15) + rand();
    

    “额外”位,如果有的话,你可以简单地扔掉(就像我上面做的那样),或者你可以保存下一个长数字。

    当然,没有免费的早餐。由于生成器内部状态的大小保持不变,并且生成的数字变长了,所以在其他地方有些东西变得“更短”了。即:这种发电机的周期变短了相应的次数。这是否重要取决于您的应用程序。

    • 4
  3. becouse
    2020-12-17T17:51:11Z2020-12-17T17:51:11Z

    这是 unsigned long long 的生成示例

     //Источник
      std::random_device rd;
    
      //Генератор
      std::default_random_engine generator(rd());
    
      // Распределение
      std::uniform_int_distribution<long long unsigned> distribution(0,0xFFFFFFFFFFFFFFFF);
    
      //Десять длинных случайных чисел
      for (int i = 0; i < 10; i++) {
          std::cout << distribution(generator) << std::endl;
      }
    

    您还可以查看Stephen Wolfram 的元胞自动机,它允许您获得任意大的适当的零和一随机序列,并在 Wolfram Mathematica 中用于生成随机数。

    它并不复杂,您可以尝试实现它。

    • 3
  4. Oh-Ben-Ben
    2020-12-17T18:47:04Z2020-12-17T18:47:04Z

    如果你有 Linux 正常读取 /dev/urandom 这样的 PRSP

    如果赢使用 mt

    这是使用 PRNG 生成数据的 4 个函数重载示例

    #include <iostream>
    #include <string>
    #include <fstream>
    #include <iterator>
    #include <random>
    #include <functional>
    #include <vector>
    
    
    template<typename T>
    void get_entropy(T* ptr, const std::size_t size) {
        if (ptr == nullptr || size == 0) {
            return;
        }
    
    #ifdef __linux__
        static std::string urandom_path{ "/dev/urandom" };
        std::fstream urandom_stream(urandom_path.c_str(), std::fstream::in | std::ios::binary);
        if (!urandom_stream.is_open()) {
            throw std::runtime_error{ "Error : Cannot open file " + urandom_path };
        }
        urandom_stream.read(reinterpret_cast<char*>(ptr), sizeof(T)* size);
        urandom_stream.close();
    #endif // __linux__
    
    #ifdef _WIN32
        static std::random_device rand_dev{};
        static std::mt19937_64 generator(rand_dev());
        auto data_size{sizeof(T) * size};
        uint64_t rand_value{0};
        while (data_size) {
            auto step_copy_size{data_size <= sizeof(rand_value) ? data_size
                                                                : sizeof(uint64_t)};
            rand_value = generator();
            std::memcpy(ptr, &rand_value, step_copy_size);
            ++ptr;
            data_size -= step_copy_size;
        }
    #endif // _WIN32
    }
    
    
    template<typename T>
    T get_entropy() {
        T ret{};
        get_entropy<T>(&ret, 1);
        return ret;
    }
    
    
    template<typename T>
    void get_entropy(T* ptr) {
        if (ptr == nullptr) {
            return;
        }
        get_entropy<T>(ptr, sizeof(T));
    }
    
    
    template<typename T>
    void get_entropy(T* begin_ptr, T* end_ptr) {
        if (begin_ptr == nullptr || end_ptr == 0) {
            return;
        }
        auto size{ end_ptr - begin_ptr };
        if (!size) {
            return;
        }
        if (size < 0) {
            get_entropy<T>(end_ptr, std::abs(size));
            return;
        }
        get_entropy<T>(begin_ptr, size);
    }
    
    
    
    template<typename T>
    T entripy_distribution(T val, T low, T height) {
        low = std::min(low, height);
        height = std::max(low, height);
        ++height;
        --low;
    
        T dist{ height - low - 1 };
    
        if (val < low) {
            auto x{ low - val };
            x = x / (dist);
            val += (x + 1) * (dist);
        }
    
        if (val > height) {
            auto x{ val - height };
            x = x / (dist);
            val -= (x + 1) * (dist);
        }
    
        return val;
    }
    
    
    struct s
    {
        s() :a(0), b(0) {}
        uint64_t a;
        uint64_t b;
    
        void print() {
            std::cout << "a :" << this->a << " b : " << this->b << std::endl;
        }
    };
    
    
    int main() {
    
        std::ostream_iterator<uint64_t> stdout_it{ std::cout, "\n" };
    
        std::cout << "Gen singl value v1 no args: " << std::endl;
    
        for (auto i{ 0 }; i < 10; ++i) {
            stdout_it = entripy_distribution<uint64_t>(get_entropy<uint64_t>(), 1'000'000'000, 2'000'000'000);
        }
    
    
        std::cout << "Gen singl value v2 ptr: " << std::endl;
        uint64_t val{ 0 };
        for (auto i{ 0 }; i < 10; ++i) {
            get_entropy<uint64_t>(&val);
            stdout_it = val;
        }
    
        std::cout << "Gen singl value v3 ptr + size: " << std::endl;
    
        for (auto i{ 0 }; i < 10; ++i) {
            get_entropy<uint64_t>(&val, sizeof(val));
            stdout_it = val;
        }
    
        std::cout << "Gen singl value v4 ptr + ptr: " << std::endl;
    
        for (auto i{ 0 }; i < 10; ++i) {
            get_entropy<uint64_t>(&val, &val + sizeof(val));
            stdout_it = val;
        }
    
        std::cout << "Gen array v1: no args" << std::endl;
        std::vector<uint64_t> v(10);
        get_entropy<uint64_t>(v.data(), v.size());
        for (const auto& val : v) {
            stdout_it = val;
        }
    
        std::cout << "Gen array v2: ptr " << std::endl;
        std::vector<uint64_t> v2(10);
        auto f{ []() {return entripy_distribution<uint64_t>(get_entropy<uint64_t>(), 0, 10); } };
        std::generate(std::begin(v2), std::end(v2), f);
        for (const auto& val : v2) {
            stdout_it = val;
        }
    
        std::cout << "Gen array v3: ptr + size " << std::endl;
        auto arr_size{ 10 };
        uint64_t* arr = new uint64_t[arr_size];
        get_entropy<uint64_t>(arr, arr_size);
        for (auto i{ 1 }; i < arr_size; ++i) {
            stdout_it = arr[i];
        }
        delete[] arr;
    
        std::cout << "Gen array v4: ptr + ptr " << std::endl;
        std::vector<uint64_t> v3(10);
        uint64_t* arr2 = new uint64_t[arr_size];
        get_entropy<uint64_t>(&(*(std::begin(v3))) + v3.size(), &(*(std::begin(v3))));
        for (const auto& val : v3) {
            stdout_it = val;
        }
    
        s obj{};
        get_entropy<char>(reinterpret_cast<char*>(&obj), sizeof(obj));
        obj.print();
    
        return 0;
    }
    
    • 1
  5. Qwertiy
    2020-12-17T18:01:03Z2020-12-17T18:01:03Z
    ((((((((unsigned long long)rand() << 15) | rand()) << 15) | rand()) << 15) | rand()) << 4) | (rand() & 15)
    
    • 0

相关问题

  • C++ 和循环依赖

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    根据浏览器窗口的大小调整背景图案的大小

    • 2 个回答
  • Marko Smith

    理解for循环的执行逻辑

    • 1 个回答
  • Marko Smith

    复制动态数组时出错(C++)

    • 1 个回答
  • Marko Smith

    Or and If,elif,else 构造[重复]

    • 1 个回答
  • Marko Smith

    如何构建支持 x64 的 APK

    • 1 个回答
  • Marko Smith

    如何使按钮的输入宽度?

    • 2 个回答
  • Marko Smith

    如何显示对象变量的名称?

    • 3 个回答
  • Marko Smith

    如何循环一个函数?

    • 1 个回答
  • Marko Smith

    LOWORD 宏有什么作用?

    • 2 个回答
  • Marko Smith

    从字符串的开头删除直到并包括一个字符

    • 2 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5