Алгоритм преобразования имени пути в уникальный номер

Я хочу преобразовать путь к Windows в уникальное целое число.

Например:

Для пути C: \ temp \ a.out, если я добавлю значение ascii для всех символов, я получу 1234. Но какой-то другой путь также может генерировать такое же число. Итак, как лучше всего сгенерировать уникальные числа для разных имен путей?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
1 343
9
Перейти к ответу Данный вопрос помечен как решенный

Ответы 9

Ответ принят как подходящий

Загляните в Хеш-функции. Обязательно учитывайте нечувствительность к регистру большинства имен файлов Windows при выполнении хеширования.

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

Здесь, в Stackoverflow, есть много вопросов, касающихся хэш-функций. Для начала просто найдите «хеш-функция». Это может быть полезным вопросом SO для вашего случая: Что такое эффективная функция хеширования строк, которая дает 32-битное целое число с низкой частотой конфликтов?.

Из-за ответа Джимми хеш-функции никогда не решат эту проблему на 100%.

Allain Lalonde 16.01.2009 20:34

@BrianLy, спасибо; Я обновил свой ответ, чтобы предоставить ссылки на ресурсы SO.

strager 16.01.2009 20:34

На практике, однако, хэш SHA-1 настолько маловероятен, что столкнется со случайным столкновением (даже со стороны злоумышленника), что на данный момент вы можете в значительной степени зависеть от него.

Eclipse 16.01.2009 21:32

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

Целые числа от -inf до + inf. Я что-то пропустил? =] Кроме того, я почти уверен, что существует ограничение на размер пути для FAT32 и / или NTFS; что-то вроде 1024 символов или что-то в этом роде. Так что, если у вас было целое число размером 1023 байта или меньше, возможно, вам не повезло. знак равно

strager 16.01.2009 20:36

@stranger: stackoverflow.com/questions/265769/… у вас есть {#_of_possible_characters} ^ 32 000 комбинаций для отображения в целочисленное значение. Да, вам чего-то не хватает;)

Giacomo 16.01.2009 20:45

@rjack: Где на плакате указано, насколько большим может быть целое число? Python 3, например, поддерживает целые числа неограниченной длины: docs.python.org/3.0/reference/…

Steve Losh 16.01.2009 20:50

@everyone: а вы, ребята, поймали меня на целочисленном. для bignums что-то вроде "pathname" .inject (1, | i, c | {i = i * 256 + c}) должно работать правильно?

Jimmy 16.01.2009 20:55

@steve losh: вам нужно 224000-битное целое число для сопоставления каждого пути, содержащего только ASCII, без коллизий. Целое число 27 КБ - это что-то недопустимое, даже если оно поддерживается языком (yay python!)

Giacomo 16.01.2009 21:04

@rjack: Что? Если имена путей состоят из 1024 символов, вам нужно не более 1024 байтов в целочисленном значении. Меньше, потому что не все символы допустимы в именах путей.

derobert 16.01.2009 21:21

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

Eclipse 16.01.2009 21:26

@rjack Да, вам понадобится огромное целое число для хранения имени пути из 32 000 символов. Но как часто вы видите пути длиной 32 000 символов? Большинство целых чисел будут крошечными и быстрыми, но в редких случаях вы все равно сможете прибегнуть к большим. Хотя, вероятно, есть еще более быстрые способы.

Steve Losh 16.01.2009 21:33

Идеальное хеширование

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

T.E.D. 16.01.2009 20:54

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

mmx 16.01.2009 22:47

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

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

Если это в Unix, вы можете просто получить его номер inode. ls -i показывает это в командной строке. Команда stat () позволяет вам получить его из программы.

Мягкие ссылки будут отображаться как один и тот же файл, а жесткие ссылки - как другой файл. Это может быть или не быть поведением, которое вы хотите.

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

Две проблемы. Во-первых, он в Windows. Я уверен, что FAT32 и NTFS имеют что-то похожее на i-node. Во-вторых, i-узлы могут изменяться там, где нет имени пути. Кроме того, ваш метод не будет работать с сетевыми путями (насколько мне известно), скорее всего, из-за того, что доступ к низкоуровневой информации о файлах будет запрещен.

strager 16.01.2009 21:01

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

Допустим, мы берем 32 000 путей символов в качестве лимита, упомянутого в одном из других комментариев. Если у нас есть 256 разных символов для использования с путями, мы получим:

Python 2.5.1 (r251:54863, May 18 2007, 16:56:43)
[GCC 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 32000L**256L
20815864389328798163850480654728171077230524494533409610638224700807216119346720596024478883464648369684843227908562015582767132496646929816279813211354641525848259018778440691546366699323167100945918841095379622423387354295096957733925002768876520583464697770622321657076833170056511209332449663781837603694136444406281042053396870977465916057756101739472373801429441421111406337458176000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000L
>>>

Обратите внимание, как Python это прекрасно представляет? Да, вероятно, есть способ лучше, но это не значит, что это невозможно.

Обновлено: rjack указал, что на самом деле это 256 ^ 32000, а не наоборот. Python по-прежнему отлично справляется с этим. Производительность может оставлять желать лучшего, но говорить, что это невозможно математически, неправильно.

это не 32000 ^ 256, а 256 ^ 32000, что имеет большое значение.

Giacomo 16.01.2009 21:10

'python -c "print pow (256, 32000)" | less '--- да, обязательно нужно меньше

Giacomo 16.01.2009 21:15

Как насчет чего-то вроде этого: Используйте хэш (String-> n бит) для каждого уровня каталога. Выделение 20 бит для каждого из 10 уровней каталогов явно не будет масштабироваться, но, возможно, уровень телескопирования битов, в предположении, что самый низкий уровень каталога будет наиболее заполненным -

например если у вас (от root) / A / B / C / D / E / F, вывести какое-то n-битное число, где

биты n / 2 - n хэшей F

биты n / 4 - n / 2 бит хэшей E

n / 8 - n / 4-битные хэши D

и т. д. и т. д.

Jimmy Said

there are more possible pathnames than integers, therefore you can't have true uniqueness. You could settle for something like an MD5 hash.

Я не думаю, что существует больше возможных имен путей, чем целых чисел. В качестве конструкции для создания уникального числа из имени пути мы можем преобразовать каждую букву в (двузначное) число (то есть от 10-25,26 =., Затем другие специальные символы, а 27 - это / - предполагается, что там меньше 89 различных символов, иначе мы можем перейти к трехзначной кодировке)

home/nlucaroni/documents/cv.pdf
1724221427232130121027242318271324122827123136251315

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

Это число явно не подходит для 64_bit unsigned int (max - 18446744073709551615), поэтому это непрактично, но мой ответ не об этом.

Вы можете прочитать здесь Лучший способ определить, являются ли два пути ссылки на один и тот же файл в C#, как можно однозначно идентифицировать путь. Вам нужно три числа (dwVolumeSerialNumber, nFileIndexHigh и nFileIndexLow), возможно, вы можете объединить эти три числа в новое число с в три раза большим количеством бит. См. Также здесь: Какие ваши любимые методы расширения для C#? (codeplex.com/extensionoverflow).

Другие вопросы по теме