LINUX.ORG.RU

Как сделать rand8 с периодом больше 256?

 ,


0

1

Сейчас вот так:

#define BXI_RAND_MULTIPLIER (1103515245)
#define BXI_RAND_INCREMENT  (12345)

static u32 global_next = 1;

static void nextrand(void)
{
    global_next = global_next * BXI_RAND_MULTIPLIER + BXI_RAND_INCREMENT;
}

void bxi_srand(u32 seed)
{
    global_next = seed;
}

<...>

u8 bxi_randu8 (void)
{
    nextrand();

    return global_next % (U8_MAX + 1);
}
https://github.com/codemeow/bixi/blob/master/code/libbixi/random/bxirand.c#L24

Проблема в том, что цикл всего 256 значений (просто каждое по одному разу) в итоге uuidv4'ы повторяются каждые 16 значений. Что можно с этим поделать и при этом не привязываясь к /dev/random?

★★★★★
static void nextrand(void)
{
    global_next = global_next * BXI_RAND_MULTIPLIER + BXI_RAND_INCREMENT;
    global_next >>= <число от 1 до 24>;
}
anonymous
()

Сделал uuidv4 через randu32х4, проблему с их периодичностью это решило.

PPP328 ★★★★★
() автор топика
Ответ на: комментарий от anonymous

В c89 шире некуда - это раз. Реализовывать длинную арифметику?
`<число от 1 до 24>' - тут по совести тоже rand нужен, но это получается парадокс Рассела.

PPP328 ★★★★★
() автор топика
Ответ на: комментарий от PPP328

Сейчас. Твой генератор очень слабый. Период для 16/32-битных чисел просто чуть больше, чем для 8-битных

anonymous
()
Ответ на: комментарий от anonymous

Генератор придумал не я, это ЛКМ, который много где юзается (glibc, Watcom, Digital Mars, CodeWarrior, IBM VisualAge C/C++, ISO/IEC 9899 и пр.)

Я имею в виду, может есть другой алгоритм, который даст такое же распределение, но больший период?

PPP328 ★★★★★
() автор топика
Ответ на: комментарий от PPP328

Деление/сдвиг просто вносит не линейность.

Все коэффициенты выбираются путем исследования такими, чтобы результирующая последовательность имела меньший период.

anonymous
()

Твоё решение (как и стандартный rand) могут использоваться только в плохих «Hello World».

и при этом не привязываясь к /dev/random?

А для чего он создан? А для чего /dev/urandom?

google://энтропия linux

UUID-ы?

Ты серьёзно? Ты хочешь их сам генерировать? Ты умнее тех, кто на этом несколько раз отстрелил себе ногу?

#include <stdio.h>
#include <uuid/uuid.h>

int main()
{
  uuid_t uuid;

  uuid_generate(uuid);

  for (size_t i = 0; i < sizeof(uuid_t); ++i) {
    printf("%.2X ", uuid[i]);
  }
  printf("\n");

  return 0;
}
AlexVR ★★★★★
()
Ответ на: комментарий от AlexVR

Ты умнее тех, кто на этом несколько раз отстрелил себе ногу?
#include <uuid/uuid.h>
e2fsprogs

Мир линуксом не ограничен, прикинь, да?

PPP328 ★★★★★
() автор топика
Ответ на: комментарий от PPP328

Мир линуксом не ограничен, прикинь, да?

Прикинь, реализации есть не только под Linux.

Прикинь, не только в libuuid реализован НОРМАЛЬНЫЙ генератор UUID-ов.

Прикинь, сколько проблем вызываю коллизии UUID-ов.

AlexVR ★★★★★
()
Ответ на: комментарий от AlexVR

Давай вообще ничего не писать, за нас все уже самые умные дядьки написали. Те самые, которые когда-то забыли, что memcpy нельзя когда память накладывается.

PPP328 ★★★★★
() автор топика
Ответ на: комментарий от I-Love-Microsoft

А, то есть теперь писать какие-либо библиотеки при существующем аналоге - извращение? Прекрасно!

Эй, вяленофаны! Тут вас извращенцами назвали!

PPP328 ★★★★★
() автор топика
Ответ на: комментарий от AlexVR

UUID-то как раз легко генерируется. В конце концов можно подглядеть в исходниках Java. Только возникают некоторые сомнения в данном конкретном случае. Лучше, конечно, когда программист математически подкован

dave ★★★★★
()
Ответ на: комментарий от dave

UUID-то как раз легко генерируется.

Только если человек понимает, что значат слова «cryptographic quality random number» в RFC 4122. А то что написано у ТС не является таким.

В конце концов можно подглядеть в исходниках Java.

Проще Boost и <random> из C++11 осилить.

AlexVR ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.