在OS X Mavericks/XCode 5.1上打破了rand()?(或者,"这是一个巨大的安全漏洞,还是我只是一个糟糕的程序员?")

use*_*072 3 c++ random macos xcode

下面的代码片段随机混乱了一个整数的STL数组 - 它在Ubuntu和Red Hat上都能正常工作.但是,在我的Mac OS X盒子上,阵列每次都会以相同的顺序混洗.代码的第二部分打印随机数生成器的输出,这绝对不是随机的.

我做错了什么,或者在升级我的OS X/XCode套件时做了些什么改变了?无论哪种方式,这是一个安全漏洞吗?...当然,许多可能用于生成随机数的遗留代码可能看起来像这样,并且突然不再是随机的.

思考?

代码(自己试试):

#include <vector>
#include <iostream>
#include <algorithm>
#include <cstdlib>

using namespace std;

int main()
{

    //First, let's initialize, shuffle, and print a random vector.
    vector<int> myOrder;

    for(int i = 0; i < 10; i++)
            myOrder.push_back(i);

    uint seed = time(NULL);
    std::srand( seed );
    std::random_shuffle(myOrder.begin(), myOrder.end());


    for(vector<int>::iterator it = myOrder.begin(); it != myOrder.end(); it++)
            cout << *it << "\t";



    //Let's check the output of the PRNG:
    cout << "\nMy seed is: " << seed << "\n==================\n";

    for(int i = 0; i < 10; i++)
            cout << rand() << "\t";

    cout << endl;
}
Run Code Online (Sandbox Code Playgroud)

在Ubuntu上运行3次输出:

4   3   6   2   7   1   9   5   0   8   
My seed is: 1395151370
==================
38394197    1995358147  65276563    2013488432  1137737660  1255414699  924908498   309981427   1799367638  1337198287  

 2  4   7   9   6   8   5   3   0   1   
My seed is: 1395151371
==================
1281137856  2008486108  1477643146  1786210280  166055115   1227183121  819984618   1762177356  207844974   1730642206  

3   6   0   5   7   8   1   4   2   9   
My seed is: 1395151372
==================
397185149   960257000   1833707166  510257843   283547169   1218814437  1818880205  1086171377  1860201155  12516048
Run Code Online (Sandbox Code Playgroud)

现在,在OS X上运行3次输出:

6   0   3   5   7   8   4   1   2   9   
My seed is: 1395151529
==================
2085289957  535188259   1247555377  1780375578  1882685795  1276101667  521534680   1552603353  530759174   1969851427  


6   0   3   5   7   8   4   1   2   9   
My seed is: 1395151530
==================
2085306764  817663508   722721803   617835589   879311078   1746312939  622562224   862970584   1989537097  1829605489  


6   0   3   5   7   8   4   1   2   9   
My seed is: 1395151531
==================
2085323571  1100138757  197888229   1602779247  2023420008  69040564    723589768   173337815   1300831373  1689359551  
Run Code Online (Sandbox Code Playgroud)

man*_*lio 5

template<class RandomIt> void random_shuffle(RandomIt first, RandomIt last);
// deprecated in C++14
Run Code Online (Sandbox Code Playgroud)

使用无法控制的实现定义的随机源.

实现经常使用std::rand,所以调用prngstd::srand种子可以工作,但它不可移植.

您可以使用带有第三个参数的random_shuffle:

C++ 11(来自http://en.cppreference.com的例子)

#include <random>
#include <algorithm>
#include <iterator>
#include <iostream>

int main()
{
    std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    std::random_device rd;
    std::mt19937 g(rd());

    std::shuffle(v.begin(), v.end(), g);

    copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
    std::cout << "\n";
}
Run Code Online (Sandbox Code Playgroud)

要么

C++ 03

...
int my_random(int i) { return std::rand() % i;}

std::srand(seed);
std::random_shuffle(myOrder.begin(), myOrder.end(), my_random);
...
Run Code Online (Sandbox Code Playgroud)