random_file_names

Вступление


Некоторые камеры категорически отказываются задавать имена файлам на основе timestamp, используя обычный счетчик. В обиходе эта мелочь действительно кажется мелочью, но в интернете вырастает в проблему, позволяющую особо любопытным шерстить сайт в поисках фотографий P1100812.jpg и P1100813.jpg после просмотра P1100811.jpg.

Варианты решения:


  • добавить статичный префикс
  • добавить динамичный префикс

Теперь надо определиться как добавить префикс, сделать ли это через самописный скрипт до загрузки фоток, переименовав все локальные фотографии (сила науки, о нет!) или в момент загрузки на сервер. Не глядя, без вздрогнутых мышц лица, был выбрал вариант «на сервер!».

Техническая реализация:


  • она есть! = пишем ручками
  • её нет! = готовый плагин для wordpress

К счастью или к сожалению, поиск плагинов выдал список outdated на старые версии wordpress. Поэтому вооружившись гуглом и затем np++ было найдено, что:
  • обработка аплоада файлов на плечах /wp-includes/functions.php
  • имя файла *генерируется в функции wp_unique_filename

*генерируется — это я немного загнул, просто проверяется на уникальность/корректность и изменяется в случае, но это, судя по коду, конечная инстанция.

И так, открываем файл functions.php, находим в нем тело функции wp_unique_filename, там строку $filename = sanitize_file_name($filename); и радостно правим её!

Как её править?

Например как (один из вариантов):
  • $filename = crc32(md5(microtime()).sanitize_file_name($filename))."_".sanitize_file_name($filename);
  • $filename = md5(microtime().sanitize_file_name($filename))."_".sanitize_file_name($filename);
  • $filename = crc32("blablabla".microtime().sanitize_file_name($filename))."_".sanitize_file_name($filename);
  • $filename = любые душе угодные хеши php и что-нибудь рандомное.sanitize_file_name($filename);

microtime() — выполняет роль ГПСЧ, выдавая текущее серверное время.

Мы оставляет текущий алгоритм работы wp_unique_filename, лишь добавляя к началу файла наш мусор.

Я для себя выбрал вариант CRC32(магия эльфов)."_".sanitize_file_name($filename);, так как CRC32 не уродует внешне файл (имя), добавляя немножко цыферек/буковок, превращая "random_file_names.png" в удобоваримый "255298064_random_file_names.png", что всяко приятнее глазу чем "ae812e87bbbf3a068807fe763721c38a_random_file_names.png".

Итог: 
  • простое решение в одну строку
  • приватные файлы чуть приватнее (хоть и в паблик системе)

Бонус:
3894406080_P1100810.jpg и 3765414138_P1100811.jpg

P1100810 P1100811

В той же папке есть P1100827.jpg

upd:
Конечно, надо понимать, что при обновлении WP может обновить (=перетереть) functions.php. Поэтому данную процедуру надо будет повторить.

Автоматизация:

Принцип: найти во всем файле строку $filename = sanitize_file_name($filename); и заменить её на выбранную вами (в примере это $filename = crc32(md5(microtime()).sanitize_file_name($filename))."_".sanitize_file_name($filename);).

Cоздать файл functions.php.diff следующего содержания в папке /wp-includes

Для префикса вида «12345_image.jpg»



--- functions.php.orig  2015-04-20 06:39:25.000000000 +0000
+++ functions.php.new   2015-05-04 17:45:27.000000000 +0000
@@ -1 +1 @@
-       $filename = sanitize_file_name($filename);
+       $filename = crc32(md5(mt_rand().microtime()).sanitize_file_name($filename))."_".sanitize_file_name($filename);


Для суффикса вида «image_12345_.jpg»



--- old.php	2015-05-06 10:39:17.847753325 +0000
+++ new.php	2015-05-06 10:39:31.459794157 +0000
@@ -1 +1,2 @@
-	$filename = sanitize_file_name($filename);
+	$filename = sanitize_file_name($filename);
+	$filename = pathinfo($filename, PATHINFO_FILENAME).'_'.crc32(md5(mt_rand().microtime()).sanitize_file_name($filename)).(pathinfo($filename, PATHINFO_EXTENSION)?'.'.pathinfo($filename, PATHINFO_EXTENSION):'');


Выполнить в папке «на сухую»
patch --dry-run functions.php -i functions.php.diff

Если все ОК, получим приблизительно такой ответ:
checking file functions.php
Hunk #1 succeeded at 1862 (offset 1861 lines).


Затем патчим по-настоящему:
patch functions.php -i functions.php.diff

Получаем ответ вида:
patching file functions.php
Hunk #1 succeeded at 1862 (offset 1861 lines).


Старый файл будет иметь имя "functions.php.orig".

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

upd2: (20150506) Добавлен вариант для суффикса между именем файла и расширением. Для файлов без расширения (если закачка таких разрешена) суффикс будет добавлен к окончанию.

upd3: (20150506) Добавлен mt_rand() и более короткий вариант для суффикса, предложенный maximw.

Комментарии (50)


  1. shasoft
    04.05.2015 19:44
    +1

    Если пользователь увидел фотографию, значит у него есть такие права, а раз есть права — значит он пусть и смотрит. Или я что-то не понимаю?

    p.s.Локально такой счетчик — тоже проблема. Фиг знает когда фотография сделана. Точнее в EXIF информация есть, но вот увидеть её можно только в просмоторщике.


    1. nikitasius Автор
      04.05.2015 19:59
      +1

      Фотографии хранятся на CDN. Статика по авторизации (=сверх короткий кеш) стоит дорого очень дорого. Можно, конечно, ввести доп параметр ?sid=[a-zA-Z0-9]{32} к примеру, без которого основа будет выдавать заглушку, но такие операции (как и авторизация) не планировались.
      Поэтому CDN сервер отдает все, что ему отдает основной сервер.


  1. Ivan_83
    04.05.2015 19:46
    +4

    «Некоторые камеры категорически отказываются задавать имена файлам на основе timestamp, используя обычный счетчик. В обиходе эта мелочь действительно кажется мелочью, но в интернете вырастает в проблему, позволяющую особо любопытным шерстить сайт в поисках фотографий P1100812.jpg и P1100813.jpg после просмотра P1100811.jpg.» — 1. Не хотите чтобы смотрели — не выкладывайте или ограничивайте доступ по взрослому — с авторизацией.
    2. Совершенно не понятно чем таймстемп лучше последовательного счётчика, учитывая его абсолютную предсказуемость.
    3. Нормальные CMS уже давно сами адекватно генерируют имена файлов, и вообще не отдают их напрямую, чтобы избегать случаев когда вместо картинки загружается код и его потом откуда то вызывают.
    4. WP решето :)


    1. nikitasius Автор
      04.05.2015 19:54

      Согласен, что timestamp не даст абсолютной защиты от "очень любопытного" пользователя. Но от "просто любопытного" защитит.

      • P20140903170712.jpg
      • P20140903170833.jpg

      Как минимум 48+33 вариантов, лучше чем 1н.
      Поэтому в статье рассмотрен вариант рандомных префиксов, которые можно перебирать достаточно долго.

      Любая система уязвима, не только WP.


      1. kriptomen
        04.05.2015 21:04
        +5

        чем 1н.
        T_T


  1. jonic
    04.05.2015 20:04
    +1

    у меня все фото отдаются по соли и id. соль a-z0-9. id просто 0-9. перебирать замучаешься :)


    1. nikitasius Автор
      04.05.2015 20:13
      -2

      То есть у вас может быть один и тот же файл, но с разными id и солью?


      1. jonic
        04.05.2015 23:09

        Вообще да, на самом деле архитектора такова что это не имеет значение. Всегда есть запись в бд и запрос идет через cdn на сервера обработки фотографий где кусок от laravel и запрос к бд, и если фото найдено, то выдается локальный редирект на nginx который уже его и отдает и ресайзит при необходимости. Помимо эоого соль помогает понять на каком сервере физически находится изображение.


  1. xpert13
    04.05.2015 20:12
    +2

    Я правильно понимаю: вы предлагаете править файл «functions.php» после каждого обновления Wordpress? Да и вообще, правка файлов CMS — моветон.


    1. nikitasius Автор
      04.05.2015 20:18
      -2

      Да, я не php программист и писать плагины под WP не умею. Правка — громко сказано, всего лишь заменить одну строчку на другую.
      На счет того, mauvais tone или нет — если CMS позволяет отключать некоторый функционал в конфигах то правка не нужна, но если она использует некоторые функции, которые никак не отключить, то, конечно, можно их поправить.


      1. xpert13
        04.05.2015 20:24
        +1

        Вы понимаете, что после обновления CMS все ваши изменения канут в Лету? Вы после каждого обновления будете проделывать эту процедуру или собираетесь отказаться от обновлений?

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


        1. nikitasius Автор
          04.05.2015 20:30
          -3

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

          Это вы загнули. Во-первых такие обновления можно автоматизировать. WP кроме вас никто не обновит. Значит после обновления запустить скрипт, который пропатчит нужный вам файл.
          Во-вторых избежать ахтунга после автопатчинга позволит чтение changelog (вы ведь их читаете?) и создание копии файла.


          1. xpert13
            04.05.2015 20:41
            +3

            Я предпочитаю решать проблемы методом «сделал и забыл», вы можете делать это как вам удобно, но зачем других так учить? Хотя бы в статью добавьте информацию о том, с какими трудностями в дальнейшем столкнется пользователь, который решит воспользоваться вашим методом.


            1. nikitasius Автор
              04.05.2015 21:44
              -1

              Очевидно, что если человек лезет во внутренности ПО и ПО обновляется, то он должен понимать, что результаты его работы могут быть перетерты. Сделал и забыл в текущих реалиях (hb/poodle) уже не работает, все приходится переделывать :)
              Добавил комментарий и diff файл.


  1. maximw
    04.05.2015 21:48
    -1

    Статья, точнее «статья», из раздела «вредные советы».

    Никогда нельзя править код CMS, только расширять предоставляемыми ею способами. Про проблемы обновления, совместимости уже выше сказали.

    Microtime — это не ГСПЧ. Если уж генерируете хеш, делайте это нормально. CRC32 — это не хеш, а код проверки целостности.

    Изучайте PHP, если это вам интересно. Полезное дело. Давать вредные советы — вредное дело, если вы не Г. Остер.


    1. nikitasius Автор
      04.05.2015 22:03

      Microtime — это не ГСПЧ.

      Статьи не читали, контекста не поняли?

      CRC32 — это не хеш, а код проверки целостности.

      Повторяю вопрос, заданный строчками выше.


      1. maximw
        04.05.2015 22:20

        Статью читал, контекст понял. Не понял, зачем публиковать такое вместо того чтоб разобраться как это делать правильно. Но дело, конечно, ваше.


        1. nikitasius Автор
          04.05.2015 23:34
          -2

          Я не вижу ничего зазорного в том, чтобы редактировать исходный код хоть WP, хоть nginx, хоть того же gnupg так, как я этого хочу, и затем использовать продукт.
          Правка кода после каждого обновлений — если это помогает решать какую-либо задачу, это уже не пустая трата времени.
          Конечно можно извернуться, вникнуть во внутреннюю архитектуру и затем сделать людям плагин, который будет жить пока совместим, а можно сделать diff, который увеличит длину ключа и буфер (как с gnupg), или расширит листинг папок со стандартных 50 символов (nginx). И еще много разного мелкого софта, где своя польза. Тот же postfix и самопальные квоты, если кто помнит.

          Поэтому фраза, что это сделано неправильно в корне неверна. Это открытое ПО с, естественно, открытым кодом. А раз код открыт, то его можно модифицировать. Главное знать что хочешь получить и что нужно править.


  1. DikSoft
    04.05.2015 23:11

    Классно, но почему префикс, а не суффикс? Сортировка же полетит к чертям. Не?


    1. nikitasius Автор
      04.05.2015 23:28
      -1

      Спасибо. Сортировка «где»?
      post_title, post_name — неизменны. Только guid отличаются. То бишь если закачали image.jpg, то только в guid будет 12345_image.jpg


  1. RubyRoid07
    05.05.2015 00:21
    -1

    Поправьте меня, если я не прав, но, похоже, что более чистого способа изменить переменную $filename в WordPress до сих пор не предусмотрено, хотя просьба добавить фильтр для функции wp_unique_filename висит с 2011 года: pytest-commit.git.net/wp-trac/msg57744.html
    Это значит, что простым плагином здесь, к сожалению, не отделаться.


    1. nikitasius Автор
      05.05.2015 10:18

      Интересный поворот, спасибо!
      Даже в ветке тикета они предлагают diff.


  1. vintage
    05.05.2015 00:55

    Зачем добавлять файлу префикс, если можно просто класть его в рандомную директорию?


    1. nikitasius Автор
      05.05.2015 10:04

      Сугубо личное мнение — неудобно. Иногда, когда консоль запущена, простой ls с копирую имя файла, чтобы кому-то скинуть ссылку и глазу приятнее видеть файлы.
      В случае с рандомными папками придется использовать find вместо ls для ручного поиска, только и всего.


  1. Lure_of_Chaos
    05.05.2015 10:04

    метод «название файла = его хэш + правильное расширение, в папке — две/три буквы этого хэша» решат указанные проблемы и бонусом: вычисление уникального содержимого; снисходительность к просмотрщикам, которые задумываются над большим кол-вом файлов в папке; это его id — если задать соотв. генератор последовательностей в базе.


    1. nikitasius Автор
      05.05.2015 10:23

      название файла = его хэш + правильное расширение, в папке — две/три буквы этого хэша

      Тогда пропадает оригинальное название файла, что для меня неприемлемо.


      1. Lure_of_Chaos
        05.05.2015 10:39

        тогда почему бы не использовать имя, данное пользователем?
        как вариант, можно вставить в случайных местах «невидимые» символы, типа неразрывного пробела, благодаря современной поддержке юникода.


        1. nikitasius Автор
          05.05.2015 10:58

          вставить в случайных местах

          Это уже больше чем 1-на строка кода, если только не писать подряд через ";" :)
          Тогда я не смогу удобно искать файлы. Файл «image_h ol idays .jpg» по слову «holidays» не найти (в папке на сервере).
          Так же если захочется сделать что-нибудь на основе аплоада WP, но без базы WP, то пробелы будут резать глаз.


  1. nikitasius Автор
    05.05.2015 11:01
    -2

    Это tutorial не человеку, который поставил WP на shared хостинг или у которого он автообновляется, а тому, кто использует его как минимум на виртуалке и перодически работает с файлами на уровне MC, а не cpanel'ного редактора.

    Большая же часть критиков пытается упростить донельзя работу с WP, поставив его в корень / apache и дав ему доступ к автоапдейтам, крайне негодуя против правки исходников as is.

    Но жизнь после install продолжается!


    1. kovalevsky
      06.05.2015 11:10

      1. Создайте файл в /wp-content/plugins/
      2. В начале файла напишите блок с комментарием:

      /**
       * Plugin Name: %Имя_Вашего_Великолепного_Плагина%
       */
      

      3. add_action на add_attachment
      4. По ID аттачмента меняйте ему имя
      5. Включайте свой плагин

      Это было бы быстрее и практичнее, чем каждый раз править файлы движка.


      1. nikitasius Автор
        06.05.2015 11:52

        Плагин в WP будет работать по принципу:

        • загрузил файл на сервер
        • взял id аттача
        • переименовал загруженный файл

        ?


        1. kovalevsky
          07.05.2015 10:28

          Да. «add_attachment» срабатывает после загрузки аттачмента и в кач-ве параметра передаст ID. По ID можно получить все данные по аттачменту и делать с ним что угодно


          1. nikitasius Автор
            07.05.2015 10:34
            -1

            В таком случае не подходит. На лицо лишние файловые операции, причем как по оригиналу так и по превьюшкам. Именно поэтому я про загрузку и спрашивал.


            1. kovalevsky
              07.05.2015 10:43

              Дело, конечно, Ваше. По мне, так проще один раз плагин на 10-15 строчек написать, чем править код движка :)


              1. nikitasius Автор
                07.05.2015 11:30

                Вот сегодня прилетело обновление и что я сделал? Я запустил patch. Не вижу трудностей.
                На сервер по ssh я могу и со смартфона зайти в любой точке мира.


                1. xpert13
                  07.05.2015 18:57
                  +1

                  Вот сегодня прилетело обновление и что я сделал? — Ничего, потому что написал плагин и в любой точке мира, даже без интернета сплю спокойно.

                  Минусы вашего решения:
                  — Нужно после каждого обновления править файлы движка
                  — Можно править движок с помощью patch, но на шаред хостинга такой вариант не прокатит
                  — Минимальные изменения в исходном коде строки, которую нужно заменить и ваш diff файл поломан, нужно его править ( опять :-( ). Да даже банальное переименование файла и вам снова нужно лезть и копаться в коде

                  Плюсы по сравнению с плагином:
                  — Меньше файловых операций. Плюс крайне сомнительный: во-первых переименование файла не самая тяжеловесная операция для винтчестера, во-вторых, вы ресурсы хостинг-провайдера так бережете?

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

                  Еще раз повторюсь: вы можете делать со своим сайтом что и как вам вздумается, это ваше право, но зачем учить плохим решениям других и еще и доказывать, что это лучшее решение?


                  1. nikitasius Автор
                    07.05.2015 19:55

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

                    Поделитесь ссылкой на ваш плагин с wordpress.org.

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

                    Вы чрезмерно драматизируете и паникуете. patch можно обернуть в bash скрипт, который проверит --dry-run проходит ли он, и если все в порядке — удаляет .orig файл и применяет diff. В противном случае сообщает пользователю что что-то поменялось внутри файла.

                    Если вдруг WP переименует functions.php, это тоже не конец света, а всего лишь новое имя файла в команде, скопировать и вставить. Далее как написано выше — если пользователь обернул patch, то его скрипт сообщит то, что он в него заложил. Иначе первый «сухой» прогон выдаст ошибку.


                    1. xpert13
                      07.05.2015 20:12

                      Так никто и не говорит, что ситуация не поправимая, но это не отменяет того, что это минусы. Для того, чтобы работал плагин не нужен доступ по SSH, не нужны патч файлы, не нужны bash скрипты и не нужно никуда лезть и что-то редактировать и менять. Всё что нужно — это установить и запустить плагин, с этим справится даже самый неопытный пользователь. Ваше решение требует наличие некоторого количества умений, больше доступа и больше телодвижений. Плагин — это отличная альтернатива решения проблемы которая лишена всех этих недостатков и ваше решение на его фоне выглядит плохим.

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


                      1. nikitasius Автор
                        08.05.2015 00:24

                        Ваше решение требует наличие некоторого количества умений, больше доступа и больше телодвижений

                        Так статья изначально была об этом. Добавление нужного функционала путем модификации софта. Что замечательно — код был улучшен и сокращен, о чем я указал.
                        А вы пытаетесь переписать ее через меня «как сделать тоже самое, но через плагин».
                        Я согласен с вами, что плагин это очень простое решение, ниже по ветке есть даже пример вроде бы рабочего плагина.
                        Теперь кому-то надо сделать статью про аналогичный функционал и про плагин + запостить таки на оффресурсе.


        1. kovalevsky
          07.05.2015 10:40

          /**
           * Plugin Name: %Имя_Вашего_Великолепного_Плагина%
           */
          
          add_action('add_attachment', function ($attachmentId) {
              $attachment = get_post($attachmentId);
              $path = get_attached_file($attachmentId);
          
              // в $path у Вас полный путь к файлу, а в $attachment - объект WP_Post вашего аттачмента
              // ... здесь Ваша логика для того, чтоб переименовать файл.
          });
          


          Вот по сути весь Ваш плагин. Вам просто нужно в объекте $attachment заменить урл в свойстве guid на новый, который будет вести к переименованному файлу. Как-то так:
          $uploads = wp_upload_dir();
          
          wp_update_post(array(
              'ID'   => $attachment->ID,
              'guid' => trailingslashit($uploads['url']) . basename($path_to_renamed_file)
          ))
          


          1. nikitasius Автор
            07.05.2015 11:29

            Опубликуйте и если оно работает, то сообщество WP скажет вам спасибо.


            1. kovalevsky
              07.05.2015 20:56

              На здоровье
              <?php
              
              /**
               * Plugin Name: Rename Attachments
               */
              
              /**
               * Class RenameAttachments
               * @package RenameAttachments
               */
              class RenameAttachments
              {
                  /**
                   * Hooks the "add_attachment" action.
                   */
                  public static function register()
                  {
                      add_action('add_attachment', array(__CLASS__, 'rename'));
                      add_filter(
                          'filter_attachment_filename',
                          array(__CLASS__, 'filterAttachmentFileName')
                      );
                  }
              
                  /**
                   * Filters attachment file name.
                   * @param string $file Attachment file name.
                   * @returns string
                   */
                  public static function filterAttachmentFileName($file)
                  {
                      return crc32(md5(mt_rand() . microtime()) . sanitize_file_name($file)) . '_' . sanitize_file_name($file);
                  }
              
                  /**
                   * Renames the attachment.
                   * @param int $attachmentId Attachment ID.
                   */
                  public static function rename($attachmentId)
                  {
                      if (!$path = get_attached_file($attachmentId)) {
                          return;
                      }
              
                      $trash = array();
                      $uploads = wp_upload_dir();
                      $original = basename($path);
              
                      $filtered = apply_filters(
                          'filter_attachment_filename',
                          $original
                      );
              
                      $images = glob(dirname($path) . '/' . pathinfo($original, PATHINFO_FILENAME) . '*');
                      if ($images === false || (is_array($images) && count($images) === 0)) {
                          return;
                      }
              
                      foreach ($images as $image) {
                          $name = str_replace($original, $filtered, $image);
                          if (copy($image, $name)) {
                              $trash[] = $image;
                          }
                      }
              
                      $path = dirname($path) . '/' . $filtered;
                      $attachedFile = str_replace($uploads['basedir'] . '/', '', $path);
              
                      if (update_post_meta($attachmentId, '_wp_attached_file', $attachedFile) === true) {
                          foreach ($trash as $file) {
                              @unlink($file);
                          }
                      }
                  }
              
              }
              
              RenameAttachments::register();
              


              1. nikitasius Автор
                08.05.2015 00:07

                Не мне публикуйте, а сообществу WP:)


  1. maximw
    06.05.2015 13:01
    +1

    	$bs_extid=strpos(strrev(sanitize_file_name($filename)),".");
    	if($bs_extid){
    		$bs_extid=strlen(sanitize_file_name($filename))-1-$bs_extid;
    		$filename = substr(sanitize_file_name($filename),0,$bs_extid)."_".crc32(md5(microtime()).sanitize_file_name($filename))."_".substr(sanitize_file_name($filename),$bs_extid);
    	} else {
    		$filename = sanitize_file_name($filename)."_".crc32(md5(microtime()).sanitize_file_name($filename)).sanitize_file_name($filename)),0,16);
    	}
    
    Зачем городить такой огород?

    $filename = sanitize_file_name($filename);
    $filename = pathinfo($filename, PATHINFO_FILENAME) . '_' . mt_rand() . (pathinfo($filename, PATHINFO_EXTENSION) ? '.' . pathinfo($filename, PATHINFO_EXTENSION) : '');
    

    И crc32(), и mt_rand() возвращают int. Зачем считать crc32 от md5 от имени файла, если проще и надежднее взять псевдослучайное число. Повторная вычислимость? Для этой задачи наоборот она не нужна. Иначе злоумышленник точно так же как просто перебрать фотки по номерам сможет заново высчитать «мусор», перебирая фотки по номерам.


    1. nikitasius Автор
      06.05.2015 13:17

      Спасибо за короткий вариант.

      md5 был не от имени файла, а от имени файла + микротайма, поэтому не перебрать по основе:)


      1. maximw
        06.05.2015 13:32

        Если злоумышленник знает время загрузки файла, то можно перебрать. И чем точнее он знает время, тем меньше запросов нужно.

        В принципе, вообще int перебрать не так сложно. Поэтому несмотря на «некрасивость», лучше использовать более длинный (в битах энтропии) «мусор».


        1. nikitasius Автор
          06.05.2015 14:03

          Обновил на ваш вариант и указал комментарий.
          Там можно помимо mtrand использовать и текстовую строку. Которую знает только владелец. "blablabla" была упомянута в статье как пример. В таком случае даже зная время создания файла и имя файла не получить следующего файла, так как неизвестна строка, участвующая в генерации.


  1. andy_shev
    06.05.2015 16:55

    Запустите на свои альбомы renrot — и дело с концом!


    1. nikitasius Автор
      06.05.2015 17:28

      Хмм, даже не слышал о нем. Я вот так делаю правильные «копии» с датойвременем:
      for file in *; do cp $file ${file}_`identify -format '%[EXIF:DateTimeOriginal]' $file|sed 's/[ :]//g'`.jpg ;done
      Можно и mv делать, если места мало.


      1. andy_shev
        06.05.2015 18:09

        Ну, он есть в поставках Debian и Fedora несколько лет как. Там хороший мануал по теме.