Hash 寻找UTF16中文件路径的良好64位哈希
我有一个Unicode/UTF-16编码路径。路径分隔符为U+005C'\'。 路径是以null结尾的根相对windows文件系统路径,例如“\windows\system32\drivers\myDriver32.sys” 我想将此路径散列为64位无符号整数。 它不需要是“加密声音”。 散列应该不区分大小写,但能够处理非ascii字母。 显然,散列也应该分散得很好 我有一些想法: A) 将windows文件标识符用作“哈希”。在我的例子中,如果文件被移动,我确实希望哈希值改变,所以这不是一个选项 B) 只需对整个字符串使用一个常规的sting散列:hash+=prime*散列+代码点 我确实觉得路径由“分段”(文件夹名和最终文件名)组成这一事实是可以利用的 总结一下需要: 1) 64位哈希值Hash 寻找UTF16中文件路径的良好64位哈希,hash,path,collision,utf-16,hash-collision,Hash,Path,Collision,Utf 16,Hash Collision,我有一个Unicode/UTF-16编码路径。路径分隔符为U+005C'\'。 路径是以null结尾的根相对windows文件系统路径,例如“\windows\system32\drivers\myDriver32.sys” 我想将此路径散列为64位无符号整数。 它不需要是“加密声音”。 散列应该不区分大小写,但能够处理非ascii字母。 显然,散列也应该分散得很好 我有一些想法: A) 将windows文件标识符用作“哈希”。在我的例子中,如果文件被移动,我确实希望哈希值改变,所以这不是一个选
2) 良好的分发/文件系统路径冲突较少。
3) 高效的
4) 不需要是安全的
5) 不区分大小写的加密安全哈希在速度方面可能不是很有效,但实际上任何编程语言都有可用的实现。
对于您的应用程序来说,使用它们是否可行取决于您对速度的依赖程度——基准测试将为您提供适当的答案 您可以使用此类散列的子字符串,例如路径上的MD5,该字符串以前已转换为小写,因此散列实际上不区分大小写(要求您使用小写方法,该方法知道如何转换文件系统中可能出现的所有UTF-16非标准字符)
加密安全散列的好处是,无论您使用哪个子字符串部分,其分布都相当均匀,因为它们被设计为不可预测的,即散列的每个部分理想地取决于整个散列数据,就像散列的任何其他部分一样。即使您不需要加密散列,也可以使用一个,既然你的问题不是关于安全性,那么一个“坏的”加密散列就可以了。我建议,这很快。在我的PC(2.4 GHz CORE2系统,使用一个核心),M4哈希超过700 Mb/s,甚至对于小的输入(小于50字节),它可以处理大约8万条消息秒。您可能会发现更快的非加密散列,但它已经需要一个相当具体的情况下,它作出了可衡量的差异 对于您所追求的特定属性,您需要:
5月份有MD4实现,包括上面的RFC1320 I链接。您还可以在中找到C和Java中的开源MD4实现。我只想使用一些简单明了的东西。我不知道您使用的是什么语言,因此以下是伪代码:
ui64 res = 10000019;
for(i = 0; i < len; i += 2)
{
ui64 merge = ucase(path[i]) * 65536 + ucase(path[i + 1]);
res = res * 8191 + merge; // unchecked arithmetic
}
return res;
ui64 res=10000019;
对于(i=0;i
我假设path[I+1]
是安全的,因为如果len
是奇数,那么在最后一种情况下,它将安全地读取U+0000
我不会利用UTF-16中的空白、小写和标题字符以及路径无效字符造成的空白这一事实,因为这些并没有以一种可以快速使用的方式分布。减少32(U+0032以下的所有字符在路径名中都是无效的)不会太贵,但也不会太多地改进哈希。您可以在C#中创建一个共享库,并使用FileInfo类获取目录或文件的完整路径。然后在路径中使用.GetHashCode(),如下所示:
Hash = fullPath.GetHashCode();
或
虽然这只是一个32位的代码,但您可以复制它或根据文件的某些其他特征附加另一个哈希代码。谢谢-但MD5和我所知道的任何其他“加密哈希”都大于64位。我得把钥匙空间折叠起来。我确实有一个方法,它是基于Unicode 5.1的小写字符串,速度非常快。是的,就像我说的,你必须使用MD5的64位子字符串。或者,看看这个问题:是的,这会起作用-我被“sub-sting”弄糊涂了-我认为它指的是文件路径,而不是结果哈希。选择这个是因为这似乎是我的最佳解决方案,并且在通信中有很好的后续效果!谢谢是的,加密散列本身不一定是坏的,因此我建议在必要时做一些基准测试进行评估。一些加密库可能会逐步取消MD4支持,因为它被认为是不安全的,因此广泛实现的MD5在可移植性和兼容性方面可能是未来的证明。据我所知,Windows支持NTFS和VFAT的Unicode文件系统名称(UTF-16;根据Wikipedia,NTFS使用16位字符,这些字符可能(但不一定)是UTF-16)。实际上,每个NTFS卷都有一个大写映射,文件系统驱动程序使用它进行不区分大小写的比较。关于速度,Java在我链接到的相关问题中使用的哈希代码对于编译语言(包括C/C++和Java)-对于dyna来说可能也是一个足够好的哈希代码
int getHashCode(string uri)
{
if (uri == null) throw new ArgumentNullException(nameof(uri));
FileInfo fileInfo = new FileInfo(uri);
return fileInfo.FullName.GetHashCode();
}