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





Загляните в Хеш-функции. Обязательно учитывайте нечувствительность к регистру большинства имен файлов Windows при выполнении хеширования.
Скорее всего, используемый вами язык предоставляет библиотечную функцию (или набор функций), которая может принимать хэш строки (или просто данных). SHA1 популярен и имеет низкую коллизию.
Здесь, в Stackoverflow, есть много вопросов, касающихся хэш-функций. Для начала просто найдите «хеш-функция». Это может быть полезным вопросом SO для вашего случая: Что такое эффективная функция хеширования строк, которая дает 32-битное целое число с низкой частотой конфликтов?.
@BrianLy, спасибо; Я обновил свой ответ, чтобы предоставить ссылки на ресурсы SO.
На практике, однако, хэш SHA-1 настолько маловероятен, что столкнется со случайным столкновением (даже со стороны злоумышленника), что на данный момент вы можете в значительной степени зависеть от него.
возможных путей больше, чем целых чисел, поэтому у вас не может быть истинной уникальности. Вы могли бы согласиться на что-то вроде хэша MD5.
Целые числа от -inf до + inf. Я что-то пропустил? =] Кроме того, я почти уверен, что существует ограничение на размер пути для FAT32 и / или NTFS; что-то вроде 1024 символов или что-то в этом роде. Так что, если у вас было целое число размером 1023 байта или меньше, возможно, вам не повезло. знак равно
@stranger: stackoverflow.com/questions/265769/… у вас есть {#_of_possible_characters} ^ 32 000 комбинаций для отображения в целочисленное значение. Да, вам чего-то не хватает;)
@rjack: Где на плакате указано, насколько большим может быть целое число? Python 3, например, поддерживает целые числа неограниченной длины: docs.python.org/3.0/reference/…
@everyone: а вы, ребята, поймали меня на целочисленном. для bignums что-то вроде "pathname" .inject (1, | i, c | {i = i * 256 + c}) должно работать правильно?
@steve losh: вам нужно 224000-битное целое число для сопоставления каждого пути, содержащего только ASCII, без коллизий. Целое число 27 КБ - это что-то недопустимое, даже если оно поддерживается языком (yay python!)
@rjack: Что? Если имена путей состоят из 1024 символов, вам нужно не более 1024 байтов в целочисленном значении. Меньше, потому что не все символы допустимы в именах путей.
Да, просто возьмите байты для имени пути и представьте, что это одно длинное целое число, и готово.
@rjack Да, вам понадобится огромное целое число для хранения имени пути из 32 000 символов. Но как часто вы видите пути длиной 32 000 символов? Большинство целых чисел будут крошечными и быстрыми, но в редких случаях вы все равно сможете прибегнуть к большим. Хотя, вероятно, есть еще более быстрые способы.
Это возможно только в том случае, если вы заранее знаете доменное пространство.
Да, другие ребята упомянули и другие вещи. Я просто отметил это для полноты картины. Это работает, например, если у вас есть статический список файлов в базе данных.
Да, вам нужно будет использовать какую-то хеш-функцию просто потому, что область вашего ввода больше, чем диапазон вашего вывода. Другими словами, правильных путей почти наверняка больше, чем чисел, представленных в типе данных вашего целевого языка.
Таким образом, полностью не сможет избежать коллизий. Если эта гарантия важна для вашего приложения, вы не сможете сделать это путем перевода в целые числа.
Если это в Unix, вы можете просто получить его номер inode. ls -i показывает это в командной строке. Команда stat () позволяет вам получить его из программы.
Мягкие ссылки будут отображаться как один и тот же файл, а жесткие ссылки - как другой файл. Это может быть или не быть поведением, которое вы хотите.
Я вижу, что многие говорят о хешировании. Этот мог работает, но теоретически, если ваш хеш делает что-то большее, чем сжимает целочисленные значения, которые недопустимы в именах файлов, тогда у вас мог есть конфликты. Если для вас это неприемлемо, тогда ваш хэш всегда будет состоять из почти такого же количества цифр, как и имя файла. В этот момент вы можете просто использовать имя файла.
Две проблемы. Во-первых, он в Windows. Я уверен, что FAT32 и NTFS имеют что-то похожее на i-node. Во-вторых, i-узлы могут изменяться там, где нет имени пути. Кроме того, ваш метод не будет работать с сетевыми путями (насколько мне известно), скорее всего, из-за того, что доступ к низкоуровневой информации о файлах будет запрещен.
Всем людям, говорящим «это невозможно, потому что у вас есть больше возможных путей, чем целых чисел для их хранения»: нет. На плакате никогда не указывался язык реализации; некоторые языки поддерживают целые числа произвольной длины. Например, 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, что имеет большое значение.
'python -c "print pow (256, 32000)" | less '--- да, обязательно нужно меньше
Как насчет чего-то вроде этого: Используйте хэш (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
и т. д. и т. д.
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).
Из-за ответа Джимми хеш-функции никогда не решат эту проблему на 100%.