我正在编写一个生成"随机"读取分配的内存部分为"随机"值。该想法基于未初始化变量具有未定义值的事实。我最初的想法是使用malloc()分配一个数组,然后使用其未初始化的元素生成一个随机数。但是malloc()往往会返回NULL内存块,所以我不能保证有任何东西要读。所以我考虑读取一个单独的进程内存,以便几乎保证NULL以外的值。我目前的想法是以某种方式找到第一个有效的内存地址并从那里读取,但我不知道如何做到这一点。我尝试将指针初始化为NULL,然后将其递增1,但如果我尝试打印引用的内存位置,则会发生分段错误。所以我的问题是如何读取单独的进程内存。除了阅读它之外,我不需要对内存做任何事情。
答案 0 :(得分:5)
不,你不能。它们具有垃圾值,这意味着无论发生在内存中的是什么,它们都不是随机的。这个想法是基于未初始化的变量具有未定义的值的事实。
答案 1 :(得分:3)
您无法读取单独的进程内存,内核会保护您不会这样做,因为它通常是由于设置指针时出错而发生的。即使它们是可能的,你也不会在随机整数附近得到任何东西。为什么不从/dev/random
读取?
答案 2 :(得分:3)
通过软件在计算机中生成随机数是HARD(有硬件随机数生成器)。新程序中的内存是一个可怕的来源,特别是在早期,因为操作系统在启动程序之前将所有内存归零。你看到的任何非零都会从初始化代码中遗留下来,留下它的污点。
假设你想要“自己动手”的数字,那么时间的微/纳秒数字就是一种旧式的解决方案......理论如下所示......用你自己的数字来玩。具有大素数的模数会很好。请务必丢弃超过1/1000秒的任何东西。
(long long)(nano * 1E10 ) % 1000
这假设您是从手动命令而不是预定作业开始的。
如果您在UNIX上运行,请查看从/ dev / urandom中读取几个字节,或者仔细阅读/ dev / random(阅读手册页)。
Windows拥有自己的API。在perl中,
new Win32::API "advapi$b32","CryptAcquireContextA",'PNNNN','N' || die "$^E\n"; # Use MS crypto or die
良好的随机数发生器为获得好的数字所做的认真工作在这里超出了快速反应;这通常依赖于硬件,例如时间戳中断。
答案 3 :(得分:3)
随机数具有某些特殊属性。计算机内存通常不满足这些属性。
如果我对计算机内存进行采样,那么它的数量就会非常相似,并且某些数字的存在概率很低,甚至可能无法在计算机的整个内存中找到它们。
更不用说如果我读取一些内存超出分配给程序的内存,操作系统会用SEGFAULT杀死我。
在许多层面上,这是一个坏主意。使用适当的随机数生成器。
答案 4 :(得分:2)
这个想法是基于未初始化的变量具有未定义的值的事实。
只要您无法预测它们包含的内容,它们就是未定义的。它主要取决于操作系统的真实含义。
回到旧的DOS时代,你可能会依赖这样一个事实:如果你在当前会话中执行了几个程序,那么内存中就会有垃圾。但即使这样,数据也不是随机性的可靠来源。
如今,情况有所不同。
如果堆栈上有变量,并且在正确的程序运行中,您从未像现在这样深入堆栈,则本地变量为0.否则,它们包含先前函数调用的数据。
如果你malloc()
并且libc从已经使用过的内存池中获取了返回的内存,那么它也可能包含垃圾。但如果它从操作系统中新获得它,则归零。
我最初的想法是使用malloc()分配一个数组,然后使用其未初始化的元素生成一个随机数。但是malloc()往往会返回NULL内存块,所以我无法保证有任何东西可以读取。
(非空,但0或NUL。)
请参阅我的最后一点:它取决于malloc()
ed区域的历史记录。
所以我考虑过读取一个单独的进程内存,以便几乎保证NULL以外的值。
你不能,因为进程是相互分离和屏蔽的。
正如其他人所说,有更好的随机性来源。 /dev/random
如果你肯定需要真正的熵,/dev/urandom
否则。{/ p>