Пользовательская случайная функция C

Я хотел бы создать быструю легкую функцию на языке C, которая возвращает псевдослучайный беззнаковый символ. Сложность для меня (программиста ANSI C) заключается в том, что я не могу использовать <stdio.h> или любые другие готовые функции. Какие-либо предложения..?

под «быстрым» я имел в виду: избегать ненужного кода (например, операторы if, циклы и т. д.) под «легким» я имел в виду: использовать как можно меньше переменных

Благодарность


person nonouco    schedule 20.06.2011    source источник
comment
Определите быстрый, легкий и случайный... Особенно случайный.   -  person Nemo    schedule 21.06.2011
comment
Является ли сложная часть синонимом требований домашнего задания?   -  person Coeffect    schedule 21.06.2011
comment
интервал ранд () {возврат 5;}   -  person President James K. Polk    schedule 21.06.2011
comment
@Dysaster хороший улов, отредактировано.   -  person President James K. Polk    schedule 21.06.2011
comment
@GregS: Я уверен, что выбран честным броском костей.   -  person Chris Eberle    schedule 21.06.2011
comment
@Chris: Взял 1024 бита из /dev/random, хэшировал их до 512 бит с помощью SHA512, затем взял результат mod 1 и добавил 5. Звучит случайно, верно?   -  person President James K. Polk    schedule 21.06.2011
comment
@GregS: тебе лучше запатентовать этот алгоритм, для меня это звучит довольно дорого.   -  person Chris Eberle    schedule 21.06.2011
comment
Согласитесь с Nemo, ваши требования слишком расплывчаты для хорошего ответа. У меня есть ответ, который точно выполняется быстро, но я не могу судить о легком или случайном, не зная больше о вашем приложении.   -  person Mark Ransom    schedule 21.06.2011
comment
@Mannimarco Прежде всего, это не университетское задание. Университетские годы давно позади. Это сложно для меня, потому что я использую stdio.h, и мне трудно думать вне его.   -  person nonouco    schedule 21.06.2011
comment
@Nemo под быстрым я имел в виду: избегайте бесполезных циклов. и легкий: используйте как можно меньше переменных.   -  person nonouco    schedule 21.06.2011
comment
11 минут и нет ссылки xkcd? ??? Что становится с SO?   -  person pmg    schedule 21.06.2011
comment
@pmg, это уже было сделано. И вы пропустили компаньона Дилберта.   -  person Mark Ransom    schedule 21.06.2011
comment
@Mark: мне больше всего нравится Дилберт. Спасибо :)   -  person pmg    schedule 21.06.2011
comment
Я отредактировал с учетом ваших заметок. рад видеть здесь столько забавных парней.. возвращение 5; был хорошим.   -  person nonouco    schedule 21.06.2011


Ответы (4)


Используйте линейный конгруэнтный генератор

E.g.

uint32_t state = 777;

char myRand()
{
   state = state * 1664525 + 1013904223;
   return state >> 24;
}

Обратите внимание, что myRand возвращает старшие биты, они более псевдослучайны, чем младшие биты.

Генераторы линейных сравнений были представлены Д. Х. Лемером в 1949 г. (см. Proc. 2nd Symp. on Large-Scale Digital Calculation Machinery (Cambridge, Mass.: Harvard University Press, 1951), 141-146). Конкретные числовые константы, которые я дал, по-видимому, взяты из Press, William H.; и другие. (1992). Численные рецепты на Фортране 77: Искусство научных вычислений (2-е изд.). ISBN 978-0-521-43064-7.

person Peter G.    schedule 20.06.2011
comment
-1: LCG не так уж и случайны, и их не следует рекомендовать для новых приложений. - person zwol; 21.06.2011
comment
Я понял ОП, что он хочет максимально простого решения. В любом случае детерминированный генератор не является случайным. - person Peter G.; 21.06.2011
comment
Если требования OP исключают что-либо лучше, чем LCRNG, то они ошибаются. - person zwol; 21.06.2011
comment
Возможно, он хочет генерировать простой низкосортный 8-битный звуковой шум, откуда мне знать? LCG как разумный выбор для этого. - person Peter G.; 21.06.2011
comment
Было бы справедливо сказать, что этот код является заимствованием у Кнута, как видно из Numerical Recipes in C, второе издание, стр. 284. - person Matěj Štágl; 24.08.2020
comment
Я проверил свою копию Кнута, получисловых алгоритмов. Кода с заданными константами или даже самих констант там нет. Все в коде, кроме выбора констант, тривиально, раз дана схема LCG. Теперь я добавил примечание о его введении Д. Х. Лемером в 1949 году и о предполагаемом источнике констант, которые я дал. - person Peter G.; 26.08.2020

Из исходного кода ядра Linux (random32.c)

значения в rnd_state должны быть инициализированы следующим образом: s1 > 1, s2 > 7, s3 > 15.

В документе утверждается, что это максимально равномерно распределенный комбинированный генератор Таусворта, основанный на коде из Научной библиотеки GNU 1.5 (30 июня 2004 г.)

struct rnd_state {
    u32 s1, s2, s3;
};

static u32 __random32(struct rnd_state *state)
{
#define TAUSWORTHE(s,a,b,c,d) ((s&c)<<d) ^ (((s <<a) ^ s)>>b)

    state->s1 = TAUSWORTHE(state->s1, 13, 19, 4294967294UL, 12);
    state->s2 = TAUSWORTHE(state->s2, 2, 25, 4294967288UL, 4);
    state->s3 = TAUSWORTHE(state->s3, 3, 11, 4294967280UL, 17);

    return (state->s1 ^ state->s2 ^ state->s3);
}

Академия: http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps

person Vinicius Kamakura    schedule 20.06.2011
comment
Может здесь? en.wikipedia.org/wiki/ - person Mark Ransom; 21.06.2011

Изобретение собственного генератора случайных чисел — плохая идея того же класса, что и изобретение собственной криптографии: легко создать что-то, что кажется способным выполнять эту работу, но на самом деле катастрофически неэффективно; построить что-то, что действительно выполняет эту работу, намного сложнее. Прочтите поучительную историю о RANDU, а затем загрузите один из вариантов Mersenne Twister и используйте его.

person zwol    schedule 20.06.2011
comment
2,5 КБ внутреннего состояния легковесны в любой современной среде, но для наиболее глубоко встроенных, и разработчики MT теперь также предлагают TinyMT, которому требуется всего 127 бит внутреннего состояния, и он все равно лучше любого LCRNG. - person zwol; 21.06.2011
comment
Это один из тех случаев, когда ОП хочет чего-то, чего не должен. Если бы ОП попросил совета по реализации RC4, вы бы ему его дали? - person zwol; 21.06.2011
comment
как вы можете знать, что он не использует микроконтроллер? - person Vinicius Kamakura; 21.06.2011
comment
В этом случае он все еще может использовать TinyMT или предложенный вами генератор Tausworthe. На самом деле, единственное, что я пытаюсь здесь понять, это то, что никто больше не должен использовать LCRNG и не пытаться заново изобретать это колесо. - person zwol; 21.06.2011
comment
хорошо, гекса понял, и я подумал, что должен заново изобрести колесо, которое было построено давным-давно. Я действительно не знаю TINYMC, но я посмотрю. спасибо - person nonouco; 21.06.2011
comment
а если серьезно, то RNG, который я предложил, довольно крут :D ядро ​​​​linux использует его, почему бы и вам не использовать? :П - person Vinicius Kamakura; 21.06.2011
comment
@Zack: Оффтоп, но по поводу RC4 проверьте используемый набор шифров в следующий раз, когда будете подключаться к большому сайту с помощью SSL... - person caf; 21.06.2011

В Википедии есть целый список генераторов псевдослучайных чисел: http://en.wikipedia.org/wiki/List_of_pseudorandom_number_generators

person Mark Ransom    schedule 20.06.2011