Как сгенерировать случайное число?

В моем приложении для Android мне нужно генерировать случайные числа,

Мое приложение будет работать на многих устройствах Android в локальной сети и использовать случайные числа для связи друг с другом. Я хочу сгенерировать такой случайный и уникальный номер, который никогда не должен быть таким же ни в одном приложении в локальной сети.

Он должен быть уникальным каждый раз, когда его генерирует любой пользователь, на своем устройстве и во всей локальной сети.

Есть идеи, буду благодарен ???


person Talib    schedule 08.09.2013    source источник
comment
Вам следует прочитать этот stackoverflow.com/questions/2982748/create-a-guid-in-java и просмотрите некоторые ссылки. Чтобы сделать то, что вам нужно, вам придется использовать некоторый алгоритм, который, помимо прочего, хеширует сетевую карту и время. Сетевая карта гарантированно уникальна. Потратьте на это немного времени и добавьте немного энтропии, возможно, что-нибудь еще на аппаратной основе, и у вас все будет хорошо.   -  person Simon    schedule 08.09.2013
comment
Было бы достаточно 32-битных целых чисел? Кроме того, из-за того, что вы хотите удалить дубликаты, какие еще статистические свойства случайности вы хотите отбросить? Почему нельзя просто посчитать последовательно (как это делает Java при назначении идентификаторов потоков)? У ссылки @ Саймона есть ноги.   -  person Bathsheba    schedule 08.09.2013
comment
32 бит должно быть достаточно, а мне просто нужен случайный и уникальный !! @Bathsheba   -  person Talib    schedule 08.09.2013
comment
@Talib, это должно быть "кирптографически" случайным или просто "совершенно" случайным?   -  person Bathsheba    schedule 08.09.2013
comment
@Bathsheba не беспокоится о безопасности или шифровании, просто случайный и всегда уникальный !!   -  person Talib    schedule 08.09.2013
comment
Если вы действительно имеете в виду всегда, вам понадобится что-то другое, кроме генератора случайных чисел. Как часто вы будете генерировать эти числа?   -  person Simon    schedule 09.09.2013
comment
это просто зависит от пользователя, это может занять несколько секунд или часов @Bathsheba   -  person Talib    schedule 09.09.2013
comment
Тогда вам следует посмотреть на UID.   -  person Simon    schedule 09.09.2013


Ответы (4)


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

Чтобы сгенерировать уникальный номер для каждого сетевого узла, довольно легко объединить IP или MAC-адрес машины со временем. Чтобы получить время, просто выполните System.currentTimeMillis();, чтобы получить свой IP-адрес, затем используйте приведенный здесь пример как получить MAC-адрес в Java. Объединив эти два числа, вы приобретете уникальность.

person SkyWalker    schedule 08.09.2013
comment
вы можете просто стереть самые важные биты даты и заполнить их IP-информацией. Это интуитивно сотрет, сколько точных миллисекунд с 1970 года нужно сказать, например 1990. Возможно, вы даже могли бы использовать String или UDT, кто сказал, что это должно быть число? - person SkyWalker; 09.09.2013

Учитывая пояснения в комментариях к вопросу, вот что я бы сделал: построил (детерминированную) схему, которая меняет местами биты в 32-битное целое число. Поменяйте местами столько, сколько хотите. Назовите это «скремблер».

Затем просто посчитайте целые числа; вызывая «скремблера» на каждом.

Уникальность гарантирована, выполняется быстро, но не является криптографически безопасным из-за детерминированного характера схемы обмена. Но обратите внимание, что в целом это будет иметь плохие свойства статистической случайности, поэтому никогда не используйте его, когда требуются равномерно распределенные случайные числа (например, Монте-Карло). Но я думаю, это должно удовлетворить ваши требования.

person Bathsheba    schedule 08.09.2013

Я не знаком с Android. Однако ваша проблема, похоже, решается с помощью UUID или универсального уникального идентификатора. Быстрый поиск в Google открывает эту страницу.

В частности, вы ищете метод _1 _, который генерирует UUID варианта 2, версии 4 (случайно сгенерированное число) в соответствии с RFC 4122.

person Escualo    schedule 08.09.2013

Вот как вы генерируете случайное число:

Random r = new Random();
int random = r.nextInt(100); // returns a value between 0 (incl) and 100 (excl)

Random r = new Random();
int random = r.nextInt(100) + 20; // returns a value between 20 (incl) and 120 (excl)

Что касается вашего вопроса о том, что номера должны быть уникальными, вы, вероятно, могли бы как-то сохранить каждый сгенерированный номер. Затем при рисовании нового случайного числа проверьте сохраненные числа, если новое случайное число уже было сгенерировано. Если да, перерисуйте.

Случайный документ Java: http://docs.oracle.com/javase/6/docs/api/java/util/Random.html

person Philipp Jahoda    schedule 08.09.2013
comment
что указывает nextInt? - person Talib; 08.09.2013
comment
Я добавил комментарий. Он возвращает случайное значение от 0 до (в данном случае) 100. - person Philipp Jahoda; 08.09.2013
comment
В принципе, неплохая идея, но производительность такой схемы со временем ухудшится. Кроме того, может увеличиться место для хранения выпавших чисел. - person Bathsheba; 08.09.2013
comment
правда, это потребует огромной обработки и замедлит работу приложения @Bathsheba - person Talib; 08.09.2013
comment
Да, это правда, но только если вы генерируете десятки тысяч (если не сотни тысяч) случайных чисел. - person Philipp Jahoda; 09.09.2013