2015-03-06 2 views
2

Я ищу генератор псевдослучайных чисел, который является «воспроизводимым» и «без гражданства». Позвольте мне уточнить: мне нужно иметь возможность повторно получать псевдослучайное число, основанное на параметре, на случайную функцию. Например (C-стиль псевдокод):Ищете альтернативный алгоритм PRNG с возможностью повторного использования/без атак

int x1 = random(1); 
int x2 = random(2); 
// and so on with lots of random() calls in between 
int new_x1 = random(1); 
// now new_x1 is like a "replay" of x1, so x1 == new_x1 

тип аргументов не имеет значения (я могу типаж все, что необходимо), возвращаемое значение не должно быть int; в конечном итоге мне понадобятся 8-битные значения.

Вопрос в том, что хороший алгоритм PRNG, который удовлетворяет требованию о том, что следующее псевдослучайное значение контролируется параметром, а не его внутренним состоянием, которое обновляется при каждом вызове? Я не то, что использовать вшивое решение, как следующее:

int random(int input) { 
    srand(input); 
    return rand(); 
} 

Это было бы инициализировать PRNG при каждом вызове, который, кажется дорогостоящим. (Я иллюстрирую этот момент, используя стандарт srand()/rand(), я знаю, что там есть лучшие алгоритмы, такие как Mersenne Twister, но идея все та же.)

+1

Вы уверены, что не просто ищете хеш-функцию? – kero

+0

Почему вы думаете, что srand стоит дорого? Это буквально просто устанавливает семена для PRNG. –

+0

@ ChrisHeald, потому что, например, алгоритм Mersenne Twister инициализирует 624 состояния при посеве. Кажется, слишком сложно сделать это, чтобы получить одно следующее псевдослучайное число. –

ответ

1

Одним из подходов, который может работать здесь, является использование блочного шифрования как AES или тройной DES. Ваш генератор псевдослучайных может быть затем

int pseudorandomValue(int input) { 
    return encryptUsingAES(input); 
} 

Это не зависит от состояния, псевдослучайной (так как выходы AES должны быть статистически неотличимы от случайных), и лиц без.

Надеюсь, это поможет!

+0

Приятное спасибо, я погружусь в него! –

+0

EDIT: При более глубоком созерцании в полной тишине я думаю, что использование AES или 3DES не будет выполнять эту работу. Причина в том, что 'encryptUsingAES (1); encryptUsingAES (1); 'даст 2 разных значения, поскольку AES осведомлен о состоянии. Правильно? –

+0

@KarelKubat AES не имеет состояния, поэтому шифрование двух значений с помощью самого блока AES (без использования случайного IV) всегда должно давать тот же результат. – templatetypedef

1

Вы можете использовать PRNG на основе Xorshift [1,2]. Этот PRNG использует предыдущее случайное число для генерации следующего. Реализация очень эффективна по сравнению с AES.

Для 32-битной реализации:

uint32_t next_rand(uint32_t prev) 
{ 
    prev ^= prev << 13; 
    prev ^= prev >> 17; 
    prev ^= prev << 5; 
    return prev; 
} 

Для реализации 64-битной:

последовательности
uint64_t next_rand(uint64_t prev) 
{ 
    prev ^= prev << 21; 
    prev ^= prev >> 35; 
    prev ^= prev << 4; 
    return prev; 
} 

случайного числа "replayable", без гражданства, а зависит только от начального значения, которое это семя.

Ссылки:

  1. Wiki: Wiki.

  2. Бумага с подробной математикой: paper.

+0

Очень приятно и выглядит абсолютно быстро. –

Смежные вопросы