1

I am writing a Bittorrent Client in C++ and need to generate a 20 Byte Peer ID. The first 8 characters are comprised of -WW1000- which represent the name of the client and the version number. The other 12 digits need to be a random number that need to be generated randomly every time the client starts.

How could I generate the 12 digit random number and concatenate it with a std::string containing the first 8 characters (-WW1000-)?

user7116
  • 63,008
  • 17
  • 141
  • 172
brnby
  • 1,433
  • 1
  • 19
  • 35

3 Answers3

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();
Andrew
  • 24,218
  • 13
  • 61
  • 90
  • 1
    This will work, as long as you don't need uniform distribution. – cdhowie Jul 23 '12 at 16:14
  • 1
    Also if two clients connect within the same period time(0) reports the same number both clients will get the same "Random" ID. Move the `srand` code outside of the function call. – Scott Chamberlain Jul 23 '12 at 16:37
2

One approach is to make a large string using rand() N times, where N is the length of the number in digits you want (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);

And if you've got a new enough C++ compiler/library:

// #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();
Community
  • 1
  • 1
user7116
  • 63,008
  • 17
  • 141
  • 172
1

I don't know how "secure" your id has to be, but because you said:

that need to be generated randomly every time the client starts,

you could probably just use that information (10 digits from seconds after 1970-01-01) and add another two random digits (00..99):

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

On my system, this will, in this moment, print:

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

    -WW1000-134306070741

If your requirements are stronger, you should, of course, use a full-random based variant.

rubber boots
  • 14,924
  • 5
  • 33
  • 44