Как лучше сгенерировать уникальное название для загружаемых файлов

123 4
LEOnidUKG
На сайте с 25.11.2006
Offline
1762
#11
domen4you:
Интересно, как на ютубе названия генерятся, символов не так много, не боятся что повторятся)

Если не изменяет память, там сделано как в укорачивании ссылок, просто по порядку.

✅ Мой Телеграм канал по SEO, оптимизации сайтов и серверов: https://t.me/leonidukgLIVE ✅ Качественное и рабочее размещение SEO статей СНГ и Бурж: https://getmanylinks.ru/ ✅ Настройка и оптимизация серверов https://getmanyspeed.ru/
G
На сайте с 13.03.2014
Offline
4
#12
LEOnidUKG:
Если не изменяет память, там сделано как в укорачивании ссылок, просто по порядку.

Понятное дело что берется инкремент предыдущей стоки) Это как автоинкримент для числовых строк в mysql. Хотя как вижу большинство генерируют рандомный набор чисел, символов и еще колдуют над ней) Не спорю для маленьких сайтов может это и допустима но для крупных проектов это не допустимо. Вопрос остается в том как это грамотно реализовать.

Yur_OK
На сайте с 13.07.2006
Offline
87
#13

Столкнулся с похожей задачей как у ТС. Напишу свое решение, возможно, кому-то пригодится.

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

Либо вы не увидели, либо не знаете что работа uniqid() основана на времени и возвращает уникальный (не повторяющийся) набор символов.

Пример

uniqid();//вернет результат - 536a23db892c8

В моем случае длина имени для файла в 13 символов, мягко говоря не устраивала, хотелось получить длину в 7-9 символов. Но возможно, вас устроит и такой вариант.

Mutabors:
А в чем проблема то? Строите свою таблицу символов, которая будет участвовать в формировании имени файла. Допустим
0123456789abc...z получаете 33-ю систему исчисления.

Интересная идея, взял ее за основу в своем решении. Однако, строить свою таблицу для перевода числа менее чем в 36-ную систему нет смысла. Т.к. это выполняет функция base_convert().

Учитывая, что результат uniqid() представляет собой целое число в 16-ой системе мы можем его сократить до 10 символов, переведя в 36-ую систему.

Пример


base_convert(uniqid(),16,36); //вернет результат - eg5z2u5ll9

Уже имеем 10 символов, лучше, но не то, что требовалось изначально.

Вот тут и принимаю решение написать перевод числа в 62-ную систему с использованием своей таблицы символов (0-9, a-z и A-Z).

Принцип работы. Результат uniqid() переводим в десятичную систему и уменьшаем его длину, после чего переводим в 62-ную и получаем уникальную строку длинной 8 символов.

Функция

function unic_name()

{
$dec = floor(base_convert(uniqid(),16,10)/10);

$wiz = Array(0 => 0, 1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5, 6 => 6, 7 => 7, 8 => 8, 9 => 9,
10 => 'a', 11 => 'b', 12 => 'c', 13 => 'd', 14 => 'e', 15 => 'f', 16 => 'g', 17 => 'h', 18 => 'i', 19 => 'j',
20 => 'k', 21 => 'l', 22 => 'm', 23 => 'n', 24 => 'o', 25 => 'p', 26 => 'q', 27 => 'r', 28 => 's', 29 => 't',
30 => 'u', 31 => 'v', 32 => 'w', 33 => 'x', 34 => 'y', 35 => 'z', 36 => 'A', 37 => 'B', 38 => 'C', 39 => 'D',
40 => 'E', 41 => 'F', 42 => 'G', 43 => 'H', 44 => 'I', 45 => 'J', 46 => 'K', 47 => 'L', 48 => 'M', 49 => 'N',
50 => 'O', 51 => 'P', 52 => 'Q', 53 => 'R', 54 => 'S', 55 => 'T', 56 => 'U', 57 => 'V', 58 => 'W', 59 => 'X',
60 => 'Y', 61 => 'Z');

while( $dec >= 1 )
{
$name = $wiz[($dec%62)].$name;
$dec /= 62;
}

return $name;
}

Пример.

unic_name();//вернет результат - FFwe6qU7
gims:
Я думаю в этом направлении. Только кто этим будет занимается? Если переложить все на php будут проблемы. Ведь нужно узнать у базы последнее значение, получить его инкремент и снова писать в бд название нового. Это не есть хорошо, поскольку в промежутке еще кто-то загрузит файл.
А вот инкремента строк в mysql не нашел..

У вас есть минимум 2 варианта.

1 – воспользоваться функцией uniqid() (результат которой основан на времени чем гарантируется уникальность создаваемых имен)

2 – взять за основу id строки. Но для этого придется выполнять 2 запроса к БД. Первый для записи информации о файле без имени, затем получаете id сделанной записи через mysql_insert_id() и генерируете короткое и уникальное имя на его основании тем же base_convert(id,10,36) затем вторым запросом обновляете поле с именем файла.

Сердце бьется, мысли зреют, мозг не спит! Облачная база каталогов (/ru/forum/708603)
87793
На сайте с 12.09.2009
Offline
661
#14
Mutabors:
Строите свою таблицу символов, которая будет участвовать в формировании имени файла. Допустим
0123456789abc...z получаете 33-ю систему исчисления.

Почему 33? 😕

36, если 10 цифр и все буквы латинского алфавита.

Наше дело правое - не мешать левому!
G
На сайте с 13.03.2014
Offline
4
#15
Yur_OK:

У вас есть минимум 2 варианта.
1 – воспользоваться функцией uniqid() (результат которой основан на времени чем гарантируется уникальность создаваемых имен)

2 – взять за основу id строки. Но для этого придется выполнять 2 запроса к БД. Первый для записи информации о файле без имени, затем получаете id сделанной записи через mysql_insert_id() и генерируете короткое и уникальное имя на его основании тем же base_convert(id,10,36) затем вторым запросом обновляете поле с именем файла.

Спасибо, уже нашел пару статей про сервисы сокращения ссылок.

В первом варианте говорить о гарантиях трудно поскольку можно предположить ситуацию где есть вероятность дублирования. Насколько ничтожной она не была.

Второй вариант это то что используют сервисы сокращения ссылок. Возможно какие-то крутые сервисы имеют собственные бд и у них все это реализовано на уровне бд. Пока бд не возьмет эту работу на себя придется несколькими запросами работать.

SeVlad
На сайте с 03.11.2008
Offline
1609
#16

А покритикуйте такое решение.

Берём полную дату+время с точностью до сотых сек. (получим число типа: 2014050718493612).

Дальше вместо каждой цифры поставим допустимые символы, им соответствующие (хоть по своей таблице, хоть др. способами).

Уникальность тут 100%, а что со скоростью\нагрузками по сравнению с мд5\mt_rand при достаточно плотной генерации результатов?

Делаю хорошие сайты хорошим людям. Предпочтение коммерческим направлениям. Связь со мной через http://wp.me/P3YHjQ-3.
Yur_OK
На сайте с 13.07.2006
Offline
87
#17
gims:
В первом варианте говорить о гарантиях трудно поскольку можно предположить ситуацию где есть вероятность дублирования. Насколько ничтожной она не была.

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

SeVlad:
А покритикуйте такое решение.

Берём полную дату+время с точностью до сотых сек. (получим число типа: 2014050718493612).

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

SeVlad:

Дальше вместо каждой цифры поставим допустимые символы, им соответствующие (хоть по своей таблице, хоть др. способами).

Это я и описал в примере которое уже предлагали выше.

Берем время (точнее не время а некая величина похожая на время с ускорением в ~4,9 %) через uniqid() и переводим в другую систему исчисления (сопоставляя каждому числу символ из таблицы в зависимости от его разрядности).

Т.е. число 146744779621792 (основанное на времени) приводится в вид FFwuMxgs

SeVlad
На сайте с 03.11.2008
Offline
1609
#18
Yur_OK:
А вы напишите функцию, которая это делает, и вызовите ее раз 100 в цикле и посмотрите результат. Увидите много повторяющихся значений даже с учетом того, что вы берете время с точностью до сотых секунд.

Речь о генерации названий файлов при их загрузке. Одновременно (с точностью до сотых сек.) файлы не могут быть загружены (или я не прав?). Отсюда - с чего бы повторяющиеся значения?

Yur_OK
На сайте с 13.07.2006
Offline
87
#19

Правы. Но! бывают разные ситуации, например при пакетной загрузке, когда нужно назначить имена сразу 30 уже загруженным файлам.

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

SeVlad
На сайте с 03.11.2008
Offline
1609
#20
Yur_OK:
например при пакетной загрузке, когда нужно назначить имена сразу 30 уже загруженным файлам.

Да хоть 100 (даже самых мелких :))! Всё равно на загрузку\генерацию_имени уйдет больше времени, чем 0,01сек на каждого. (Для особо параноидальных случаев можно и с точностью до 0,001 сек генерировать :))

В уникальности имён* в моём варианте я уверен . А вот в целесообразности (скорости\нагрузки и тд) - сомневаюсь.

* для задач в стартпосте.

123 4

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий