Могу ли я использовать адрес argc в main как случайный источник?
Я хочу создать программу, которой нужно только одно случайное число, поэтому я пытаюсь использовать адрес argc в основной функции в качестве случайного источника, потому что я думаю, что расположение программы в памяти является случайным, а также она может сохранять некоторые операторы включения, поэтому я попробовал:
#include <stdio.h>
int main(int argc,const char* argv[]){
printf("%lu\n",(unsigned long int)&argv/sizeof(unsigned long int));
return 0;
}
но я обнаружил, что вывод в каждый раз не очень "случайный": они кратны 4:
17591828907268
17591841542404
17591845040388
17591834556676
Какова причина? И возможно ли использование адреса argc в качестве случайного числа?
Затем я пытаюсь удалить некоторые биты адреса:
#include <stdio.h>
int main(int argc,const char* argv[]){
printf("%lu\n",(unsigned long int)&argv >> 12);
return 0;
}
на этот раз он выглядит довольно случайным, по крайней мере, у него есть как нечетные, так и четные числа:
34359070631
34359034616
34359078055
34359080624
это "правильный" способ превратить адрес argc в случайное число?
3 ответа
Какова причина?
Требования выравнивания для вашей архитектуры, которые я предполагаю, x86 и int
4 байта, что означает каждый int
должен быть выровнен по адресу, который делится на 4 (это именно то поведение, которое вы видите).
И возможно ли использование адреса argc в качестве случайного числа?
Возможный? Да, конечно. Вы просто идете и делаете это.
Это хорошая идея? Нет, определенно нет. Смотрите ниже, почему.
Это "правильный" способ превратить адрес argc в случайное число?
Я предполагаю, что под "правильным" вы подразумеваете хороший источник энтропии, и ответ на этот вопрос - нет.
В современных операционных системах существует некоторая степень рандомизации расположения адресного пространства, но она не является хорошим источником энтропии. Это просто для того, чтобы кому-то было труднее использовать ошибку в вашей программе в качестве эксплойта безопасности. И на самом деле нет никаких гарантий относительно ASLR (вы можете отключить его в некоторых операционных системах, если вы действительно этого хотите).
Короче говоря, вы не должны использовать адрес переменной в качестве источника энтропии. Это просто не хороший источник случайности.
Если вам действительно нужна случайность, вы должны использовать одно из:
- / DEV / случайное
/ DEV / urandom
Для информации об этих двух см. Как использовать / dev/random или urandom в C?
srand()
Информация о посеве srand() находится здесь: Рекомендуемый способ инициализации srand?
Внешняя библиотека, специально предназначенная для этого.
Некоторая информация здесь Хороший генератор случайных чисел для C
Это кратно 4, потому что адреса функций будут выровнены по словам на каждой платформе, о которой я знаю (я предполагаю, что это x86 или x86_64?)
Адрес argc может быть "случайным" для некоторого смысла слова, в том смысле, что вы, вероятно, не будете знать, что это такое, поэтому, если вы используете это, чтобы заполнить начальные условия для игры или что-то, что, вероятно, будет работать; определенно не полагайтесь на это, если вы используете это для шифрования или чего-то еще - злоумышленник может сделать что-то, чтобы повлиять на загрузку argc.
Тем не менее, ваша библиотека C поставляется с прекрасно работающими функциями rand() и srand(), которые в качестве бонуса позволяют вам преднамеренно заполнить ее определенным значением, которое может быть очень полезно при отладке; Я придерживаюсь этого, когда мне нужны случайные числа, лично.