Как использовать boost::uuids::uuid для преобразования в 128/64-битные числа?

Я использую этот код для создания UUID из boost:

boost::uuids::random_generator gen;
boost::uuids::uuid uuidId = gen();
string randomUUID = boost::lexical_cast<std::string>(uuidId);
std::remove( randomUUID.begin(), randomUUID.end(), '-');
randomUUID = "0x" + randomUUID;

Это дает мне шестнадцатеричные числа, например: «0xCC5B9F6946EF4448A89EDB2042E0B084».

Мой вопрос: как преобразовать эту строку (128-битное шестнадцатеричное число) в 128-битную длину ИЛИ 64-битную длину (это нормально, чтобы потерять более высокие данные)?

Стандарт C atoll и C++ std::stoll в этом случае не помогают.

UUID предпочтительнее для случайного качества генерации.

Спасибо!


person Alec H    schedule 28.04.2016    source источник
comment
Использование UUID для генерации случайных чисел — ужасная идея. У них нет энтропии аналогичного, правильно сгенерированного случайного числа с использованием чего-то вроде вихря Мерсенна. Сделайте себе одолжение и на самом деле используйте функциональность, встроенную в стандартную библиотеку C++, для генерации случайных чисел подобно этому. Кроме того, брать подстроки UUID — это просто плохая идея   -  person Mike Vine    schedule 28.04.2016
comment
У меня Mersener Twister и в моем случае это выглядит так:   -  person Alec H    schedule 29.04.2016
comment
У меня есть Mersener Twister, и в моем случае это выглядит так: auto const seed = std::random_device()(); std::mt19937 mt(seed); std::uniform_int_distribution‹int› dist(12345678, 99999999); длинный л1; длинный л2; for (int i=0; i‹10; ++i) { l1 = dist(mt); l2 = расстояние (мт); std::cout ‹‹ l1 ‹‹ l2 ‹‹ \n; } Я думаю, что UUID может предоставить более качественные случайные числа.   -  person Alec H    schedule 29.04.2016
comment
boost::uuids::random_generator использует Mersenne Twister. Поэтому нет оснований ожидать, что он обеспечит более качественную генерацию случайных чисел, чем прямое использование Mersenne Twister. И, как говорит Майк, использование подстроки UUID для генерации случайного числа кажется странным.   -  person Chris Drew    schedule 29.04.2016


Ответы (2)


Если все, что вам нужно, это случайное 64-битное целое число без знака, вы можете просто использовать стандартный С++ 11:

std::mt19937_64 engine(std::random_device{}());
std::uniform_int_distribution<uint64_t> distribution;
auto ui64 = distribution(engine);

Демо.

person Chris Drew    schedule 29.04.2016
comment
А исключения?! - person Norbert Boros; 22.08.2019

Это работает так, но энтропия нуждается в исследовании:

typedef unsigned long long ull;
//...
ull ui64 = 0;
const int startPosition = 18;//can vary - we can use rand() too
const int lengthHex = 14;//can vary - we can use rand() too
boost::uuids::random_generator gen;
boost::uuids::uuid uuidId = gen();
string randomUUID = boost::lexical_cast<std::string>(uuidId);
std::remove( randomUUID.begin(), randomUUID.end(), '-');
randomUUID = "0x" + randomUUID.substr(startPosition, lengthHex);
ui64 = std::stoull(randomUUID, 0, 16); //random out of UUID
std::cout << ui64 << '\n';
person Alec H    schedule 29.04.2016