34: it.it_value.tv_sec = interval;
35: setitimer(ITIMER_REAL, , NULL);
36:
37: while (1) pause();
38: }
39:
40: return child;
41: }
42:
43: void stop_timer(pid_t child) {
44: kill(child, SIGTERM);
45: }
46:
47: int main (int argc, const char **argv) {
48: pid_t timer = 0;
49:
50: printf("Демонстрация интервальных таймеров для 10 секунд, "
51: "ожидайте...\n");
52: timer = start_timer(1);
53: sleep(10);
54: stop_timer(timer);
55: printf("Готово.\n");
56:
57: return 0;
58: }
Глава 19
Случайные числа
Слово
Однако некоторые приложения (включая криптографические) для достижения наилучших результатов требуют использования действительно случайных чисел. Ядро Linux для предоставления криптографически устойчивых случайных чисел производит выборку событий из непредсказуемого внешнего мира.
Все компьютеры поддаются прогнозированию. В большинстве задач, которые мы поручаем компьютеру, предсказуемость является наиболее важным обстоятельством. Даже если в вашей программе появляются ошибки, необходимо, чтобы их возникновение было предсказуемым, иначе вы не сможете найти их и ликвидировать.
19.1. Псевдослучайные числа
В некоторых ситуациях все же требуется обеспечить невозможность прогнозирования. Библиотека С содержит функции для генерирования ожидаемых последовательностей псевдослучайных чисел. Эти функции легки в применении и являются одинаковыми на всех платформах Unix. Рассмотрим пример типичного использования данных функций.
#include
#include
srand(time(NULL) +getpid());
for (...;...;...) {
do_something(rand());
}
Общепринято в качестве time()
. Последняя возвращает количество секунд, прошедших с 1 января 1970 года, поэтому начальное значение изменяется каждую секунду. Таким образом, оно может считаться уникальным в течение достаточно длинного интервала времени (приблизительно 49 710 дней на 32-разрядном компьютере). Если необходимо предотвратить возможность одинаковой активизации программы для двух пользователей, которые запускают ее в одну и ту же секунду, добавьте в начальном значении ко времени идентификатор текущего процесса.
Числа, возвращаемые функцией rand()
, удовлетворяют математическим свойствам случайного распределения, но не обладают высокой энтропией (уровнем неупорядоченности). Для достаточно больших выборок они хорошо распределены в пределах всевозможных 32-битовых чисел, однако для одного и того же начального значения можно получить различные наборы чисел. Это означает, что такие псевдослучайные числа пригодны почти для всех приложений, требующих случайного распределения чисел. К таким приложениям относятся игры, методы Монте-Карло (здесь важно сохранить начальное значение, чтобы любой желающий мог проверить ваши результаты), а также протоколы, которые обрабатывают коллизии путем ввода случайной задержки.
Обратите внимание на то, что при отладке вам потребуется сохранить начальное значение, с которым была вызвана функция srand()
. Если во время работы программы происходит ошибка, зависящая от данных, переданных функцией rand()
, то вы можете использовать это значение для вывода того же самого потока случайных чисел и воспроизведения ошибки.
19.2. Криптография и случайные числа
Мы не являемся экспертами в области криптографии. Написание программного обеспечения шифрования — это чрезвычайно искусное дело, и тот, кто берется за него без соответствующих исследований, не сможет создавать устойчивые и надежные криптографические приложения. Эта глава преследует две и только две цели.
• Убедить тех программистов, которые не являются специалистами в шифровании, оставить работу в этой области экспертам.
• Продемонстрировать криптографическим знатокам очень удобный инструмент, доступный для применения.
Если вы недостаточно хорошо знакомы с криптографией, однако вынуждены ее применять, мы рекомендуем [30] в качестве превосходного вводного руководства по этой теме.