2012-07-23 246 views
1

我正在用C++写一个Bittorrent客户端,需要生成一个20字节的Peer ID。前8个字符由代表客户名称和版本号的-WW1000-组成。其他12位数字需要是随机数,每次客户端启动时需要随机生成一个随机数。你如何生成一个随机的12位数字?

如何生成12位数的随机数并将其与包含前8个字符(-WW1000-)的std::string连接?

回答

5
const string CurrentClientID = "-WW1000-"; 
ostringstream os; 
for (int i = 0; i < 12; ++i) 
{ 
    int digit = rand() % 10; 
    os << digit; 
} 
string result = CurrentClientID + os.str(); 
+1

只要你不需要均匀分配,这将工作。 – cdhowie 2012-07-23 16:14:40

+1

同样,如果两个客户端在相同的时间段内连接(0)报告相同的数字,则两个客户端将获得相同的“随机”ID。将'srand'代码移到函数调用之外。 – 2012-07-23 16:37:54

+0

@ScottChamberlain:好点!删除了srand – Andrew 2012-07-23 16:47:16

2

一种方法是使用rand() N次,其中N是多少你想要的数字长度(a naive way to avoid modulo bias)做一个大的字符串:

size_t length = 20; 
std::ostringstream o; 

o << "-WW1000-"; 
for (size_t ii = 8; ii < length; ++ii) 
{ 
    o << rand(); // each time you'll get at least 1 digit 
} 

std::string id = o.str().substr(0, length); 

如果你已经有了一个新的足够的C++编译器/库:

// #include <random> 
std::random_device r; 
std::mt19937 gen(r()); 
std::uniform_int_distribution<long long> idgen(0LL, 999999999999LL); 

std::ostringstream o; 
o << "-WW1000-"; 
o.fill('0');  
o.width(12); 
o << idgen(gen); 

std::string id = o.str(); 
1

我不知道如何“安全”您的ID必须是,而是因为你说:

that need to be generated randomly every time the client starts

你很可能只是使用该信息(从1970-01-01秒后10位数字),又增加两个随机数字(00..99):

using namespace std; 
... 
... 
ostringstream id; 
id << "-WW1000-" << setw(10) << setfill('0') << time(0) << setw(2) << rand()%100; 
... 

在我系统,这种意志,在这一刻,打印:

cout << id.str() << endl; 

    -WW1000-134306070741 

如果你的要求是更强的,你应该,当然,使用完全基于随机变异。