действительно уникальное случайное число генерируется с помощью php? - PullRequest
0 голосов
/ 14 мая 2010

Я создал скрипт php для размещения большого количества изображений, загружаемых пользователем, каков наилучший способ генерирования случайных чисел для имен файлов изображений, чтобы в будущем не возникало конфликта имен файлов? Будь как Imageshack. Спасибо.

Ответы [ 10 ]

11 голосов
/ 14 мая 2010
$better_token = uniqid(md5(mt_rand()), true);
9 голосов
/ 14 мая 2010

Самый простой способ - это новый GUID для каждого файла.

http://www.php.net/manual/en/function.uniqid.php#65879

2 голосов
/ 25 мая 2011

Вот как я реализовал ваше решение

В этом примере предполагается, что я хочу

  • Получить список, содержащий 50 уникальных и случайных чисел, и
  • Этот список # должен быть в диапазоне от 0 до 1000

Код:

 //developed by www.fatphuc.com

 $array = array(); //define the array

 //set random # range
 $minNum = 0;
 $maxNum = 1000;

// i just created this function, since we’ll be generating
// # in various sections, and i just want to make sure that
// if we need to change how we generate random #, we don’t 
// have to make multiple changes to the codes everywhere. 
// (basically, to prevent mistakes)

function GenerateRandomNumber($minNum, $maxNum){
   return round(rand($minNum, $maxNum));
}

//generate 49 more random #s to give a total of 50 random #s
for($i = 1; $i <= 49; $i++){
    $num1 = GenerateRandomNumber($minNum, $maxNum);   
        while(in_array($num1, $array)){
            $num1 = GenerateRandomNumber($minNum, $maxNum);
        }   
    $array[$i] = $num1;
}

asort($array); //just want to sort the array

//this simply prints the list of #s in list style
echo '<ol>';
foreach ($array as $var){
    echo '<li>';
    echo $var;
    echo '</li>';
}
echo '</ol>';
1 голос
/ 14 мая 2010

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

Не лучше ли использовать хеш файла данных - таким образом вы получите добавленное преимущество обнаружения дублированных представлений.

Если обнаружение дубликатов известно как не проблема, то я все равно рекомендовал бы этот подход, но изменил бы вывод на основе обнаруженных коллизий (но используя гораздо более дешевый метод вычисления, чем предложенный Lo 'oris) например

 $candidate_name=generate_hash_of_file($input_file);
 $offset=0;
 while ((file_exists($candidate_name . strrev($offset) && ($offset<50)) {
    $offset++;
 }
 if ($offset<50) {
    rename($input_file, $candidate_name . strrev($offset));
 } else {
    print "Congratulations - you've got the biggest storage network in the world by far!";
 }

это даст вам возможность хранить около 25 * 2 ^ 63 файлов с использованием хэша sha1.

Что касается того, как генерировать хеш, чтение всего файла в PHP может быть медленным (особенно если вы пытаетесь прочитать все это в одну строку, чтобы хэшировать его). Большинство систем Linux / Posix / Unix поставляются с такими инструментами, как 'md5sum', которые очень эффективно генерируют хэш из потока.

C.

1 голос
/ 14 мая 2010

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

1 голос
/ 14 мая 2010

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

Вы также можете использовать инкрементный подход к присвоению этих чисел, например, объединениеtimestamp_part, основанное на текущем времени и random_part, просто для того, чтобы избежать коллизий, если несколько пользователей загружают файлы одновременно.

0 голосов
/ 07 июня 2017

Гарантия уникальности не может быть случайной. Случайное не может быть гарантировано уникальным. Если вы хотите уникальный (без случайного), то просто используйте целые числа: 0, 1, 2, ... 1235, 1236, 1237, ... Определенно уникальный, но не случайный.

Если это не подходит, то вы можете быть совершенно уникальным с появлением случайного. Вы используете шифрование целых чисел, чтобы они выглядели случайными. Использование DES даст вам 32-битные числа, в то время как использование AES даст вам 64-битные числа. Используйте либо для шифрования 0, 1, 2, ... в порядке с тем же ключом. Все, что вам нужно сохранить, это ключ и следующий номер для шифрования. Поскольку шифрование является обратимым, зашифрованные номера гарантированно уникальны.

Если 64-битные или 32-битные числа слишком велики (32 бита - это 8 шестнадцатеричных цифр), посмотрите на формат, сохраняющий шифрование, который даст вам меньший диапазон размеров при некоторой стоимости во времени.

0 голосов
/ 14 мая 2010

Моим решением обычно является хеш (MD5 / SHA1 / ...) содержимого изображения. Это дает дополнительное преимущество, заключающееся в том, что если люди загружают одно и то же изображение дважды, у вас остается только одно изображение на жестком диске, что экономит некоторое пространство (конечно, вы должны убедиться, что изображение не удалено, если один пользователь удаляет его, а другой пользователь имеет используется то же изображение).

0 голосов
/ 14 мая 2010
  1. подделать имя файла
  2. попробуйте открыть этот файл
  3. если существует, переходите к 1
  4. создать файл
0 голосов
/ 14 мая 2010

Возможно использование чего-либо, основанного на временной метке. Подробнее см. Функцию microtime . Или uniqid для создания уникального идентификатора на основе текущего времени.

...