2

我想将 Windows 路径名转换为唯一整数。

例如:

对于路径名 C:\temp\a.out,如果我添加所有字符的 ascii 值,我得到 1234。但其他一些路径也可以生成相同的数字。那么,为不同的路径名生成唯一编号的最佳方法是什么?

4

9 回答 9

12

查看哈希函数。确保在执行散列时考虑大多数 Windows 文件名不区分大小写的特性。

最有可能的是,您使用的语言提供了一个库函数(或函数集合),它可以获取字符串(或只是数据)的哈希值。 SHA1很受欢迎,并且碰撞率低。

在 Stackoverflow 上有很多关于哈希函数的问题。为了让您开始,只需搜索“散列函数”。对于您的情况,这可能是一个有用的 SO 问题:什么是高性能字符串散列函数,可以产生低冲突率的 32 位整数?.

于 2009-01-16T17:30:13.377 回答
8

可能的路径名比整数多,因此您不能拥有真正的唯一性。你可以接受像 MD5 哈希这样的东西。

于 2009-01-16T17:30:22.330 回答
2

完美的散列

于 2009-01-16T17:31:14.560 回答
2

是的,您需要使用某种散列函数,因为输入的域大于输出的范围。换句话说,几乎可以肯定,有效路径名比目标语言数据类型中可表示的数字多。

所以不可能完全避免碰撞。如果此保证对您的应用程序至关重要,您将无法通过转换为整数来实现。

于 2009-01-16T17:32:08.833 回答
1

像这样的事情怎么样:为每个目录级别使用(字符串-> n 位)的哈希值。为 10 个目录级别中的每一个分配 20 位显然不会扩展,但可能是可伸缩级别的位,假设最低的目录级别将是最多的 -

例如,如果你有(从根)/A/B/C/D/E/F,输出某种 n 位数字,其中

位 n/2 - n 散列 F

位 n/4 - n/2 位散列 E

n/8 - n/4 位散列 D

等等等等

于 2009-01-16T18:20:29.610 回答
0

如果这是在 Unix 上,你可以抓住它的 inode 号。ls -i 在命令行上显示它。stat()命令允许您从程序中检索它。

软链接将显示为同一个文件,而硬链接将显示为不同的文件。这可能是也可能不是您想要的行为。

我看到很多人在谈论哈希。这可能有效,但理论上,如果您的哈希所做的不仅仅是压缩文件名中不允许的整数值,那么您可能会发生冲突。如果这对您来说是不可接受的,那么您的哈希值总是几乎与文件名一样多。此时,您不妨只使用文件名。

于 2009-01-16T17:50:26.173 回答
0

对于所有人说“这是不可能的,因为你有比整数更多的可能路径来存储它们”:不。张贴者从未指定实现语言;一些语言支持任意长度的整数。以 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 仍然可以很好地处理它。性能可能会有一些不足之处,但说它在数学上不可能是错误的。

于 2009-01-16T18:06:19.823 回答
0

吉米说

可能的路径名比整数多,因此您不能拥有真正的唯一性。你可以接受像 MD5 哈希这样的东西。

我认为没有比整数更多的可能路径名。作为从路径名创建唯一数字的结构,我们可以将每个字母转换为(两位数)数字(所以从 10-25,26=.,然后是其他特殊字符,27 是 /——假设有少于 89 个不同的字符,否则,我们可以移动到三位编码)

home/nlucaroni/documents/cv.pdf
1724221427232130121027242318271324122827123136251315

这形成了一个双射(虽然,如果你只计算有效的路径名,那么满射属性就会失败,但通常人们并不关心那个持有)——想出一个不是整数的路径。

这个数字显然不适合 64_bit unsigned int(最大值为 18446744073709551615),所以它不实用,但这不是我回答的重点。

于 2009-01-16T18:22:09.497 回答
0

您可以在此处阅读Best way to determine if two path reference to the same file in C# how you can uniquely identify a path。您需要三个数字(dwVolumeSerialNumber、nFileIndexHigh 和 nFileIndexLow),也许您可​​以将这三个数字组合成一个具有三倍多位的新数字。另请参阅此处:您最喜欢的 C# 扩展方法是什么?(codeplex.com/extensionoverflow)

于 2009-01-16T18:22:12.647 回答