Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何将目录路径转换为唯一的数字标识符(Linux/C+;+;)?_C++_Linux_Hash_Uniqueidentifier - Fatal编程技术网

C++ 如何将目录路径转换为唯一的数字标识符(Linux/C+;+;)?

C++ 如何将目录路径转换为唯一的数字标识符(Linux/C+;+;)?,c++,linux,hash,uniqueidentifier,C++,Linux,Hash,Uniqueidentifier,我正在研究获取目录(文件夹)并派生某种形式的唯一数字标识符的方法。我已经研究过“字符串到散列”的方法,但是,这意味着我们永远无法为每个字符串推导出一个真正唯一的数字 字符串到唯一散列是不好的 我最近一直在研究实现目标的其他方法,因此有以下问题要问: 目录时间戳-它们有多“独特”? “stat”报告的时间戳的分辨率如何(第二次发布)?如果分辨率足够小,那么在Linux系统上是否可能有多个文件夹共享完全相同的时间戳 如果有人想分享其他方法/技巧,我很乐意倾听:) 编辑1澄清我的使用案例,以回应目前发

我正在研究获取目录(文件夹)并派生某种形式的唯一数字标识符的方法。我已经研究过“字符串到散列”的方法,但是,这意味着我们永远无法为每个字符串推导出一个真正唯一的数字

字符串到唯一散列是不好的

我最近一直在研究实现目标的其他方法,因此有以下问题要问:

目录时间戳-它们有多“独特”? “stat”报告的时间戳的分辨率如何(第二次发布)?如果分辨率足够小,那么在Linux系统上是否可能有多个文件夹共享完全相同的时间戳

如果有人想分享其他方法/技巧,我很乐意倾听:)

编辑1澄清我的使用案例,以回应目前发布的答案:我在Android平台上工作,因此文件系统没有链接到任何其他平台(当然,除了Micro SD卡等可移动媒体)

我将每个路径插入数据库,但在查询表时尽量避免字符串比较。这里不允许使用映射/哈希映射。是的,路径本身是唯一的,但理想情况下,我需要一个数字标识符,可以用来查询表,而不是路径本身。每个路径的标识符也必须是唯一的。我用std::collate做过实验,但发现散列中有很多冲突(一个包含20000条路径的数据集大约有100个冲突)。更令人惊讶的是,每次运行我的应用程序时,哈希值似乎都大不相同。我想知道它是不是种下了种子

非常感谢,,
P

在任何基于UNIX的系统上,您都可以使用inode编号作为该文件系统中的唯一标识符。将其与设备编号相结合将使其在机器中唯一。如果您希望它是全局唯一的,您可以输入系统的主MAC地址

但是,请记住:

  • 如果目录被移动或重命名,inode编号将“跟随”目录。如果目录被删除和替换,它将更改

  • 除了一两个真正特殊的目录外,inode编号在系统中不会稳定。(例如,
    /
    通常是索引节点2。)

  • +一个黄昏,好的一个

    另一种方法是简单地将dir的路径视为一个数字(“BigInt”)

    以这个目录为例:
    /opt/www/log

    它有12个字符长。
    12*8位=96位
    因此,您有一个96位长的数字,可以用十六进制/base64/任何形式表示(以防需要将其作为HTML链接传递)


    不过,我个人倾向于duskwuff的方法。

    我认为这在很大程度上取决于为什么需要唯一的数字标识符。时间戳可以改变,索引节点可以改变,磁盘号可以改变,MAC地址可以改变。(仍然,黄昏乌夫+1)

    在某些情况下,您可以简单地创建一个表,其中添加的每个路径都会获得一个新的唯一编号,就像数据库中的数字键列一样

    尽管散列可能会发生冲突,但在每个实际环境中,这是绝对不可能的(如果您不使用最糟糕的算法…),因为实现中的缺陷而导致错误的可能性更大,例如您对待“/tmp”的方式不同于“/tmp/”,因为在散列路径之前不会对路径进行规范化。或者,您希望区分物理文件夹,但忘记检查指向同一文件夹的硬链接和符号链接,因此同一目录会有多个哈希/id

    同样,根据您的用例,冲突不一定是致命的:如果您发现新路径产生与现有路径相同的哈希(不会发生!),您仍然可以对该情况做出反应。(*)

    只是为了帮助你的想象力:如果你使用64位哈希,你可以用空文件夹(除了短文件夹名外,没有其他内容)填充15万个1TB硬盘驱动器,然后你肯定会遇到冲突。如果你认为这太危险了(眨眼,眨眼),那么使用128位的散列,这样做的可能性要小18 446 744 073 710 000倍

    散列的设计目的是使冲突不太可能发生,如果没有人愿意尝试产生冲突,即使是好的旧MD5也能很好地完成它的工作

    (*)编辑:
    您的鸽子洞文章已经指出:冲突只是意味着查找不再是O(1),而是稍微慢一点。因为它很少发生,你可以很容易地接受它。如果使用std::map(无散列)或std::hashmap,就不必担心冲突。请参见

    假定每个文件夹的绝对路径由唯一的字符序列描述。或者你必须允许重复?所有目录都在同一个卷上吗?@juanchopanza,这不太符合数字标识符的条件,因为人们通常理解数字标识符。时间戳也不能满足要求,因为您可以将它们设置为您想要的任何值(
    stat
    只按秒报告它们,不管FS的分辨率如何)。虽然理论上,您可以将两条路径散列到同一个值,但实际上,如果使用合适的散列,这永远不会发生。理论上的担忧压倒了实际的担忧,这有什么原因吗?另一个问题:“数字标识符”有大小限制吗?P.S如果您可以确定某些字符永远不会出现在路径中,您可能会节省一些位。在inode中指向同一个字符的两个不同路径将以相同的标识符结束。我不知道这是否可以接受。谢谢你,达斯沃夫。我感谢你的意见!我已经更新了我的问题以澄清我的用例。谢谢你,丹尼尔。我已经更新了我的问题,以便更好地描述我的用例。