好的,我需要一个哈希函数来满足以下要求。这个想法是能够将属于同一逻辑结构但存储在文件系统的不同物理区域中的目录链接在一起。
我需要用 Java 实现它,它必须在执行会话之间保持一致,并且可以返回 long。
我将对目录名称/字符串进行哈希处理。这应该有效,以便 "somefolder1"
和 "somefolder2"
将返回不同的哈希值,"JJK"
和 "JJL" 也会返回不同的哈希值
。我还想了解何时可能发生冲突。
有什么建议吗?
谢谢
Ok, I need a hashing function to meet the following requirements. The idea is to be able to link together directories that are part of the same logical structure but stored in different physical areas of the file system.
I need to implement it in Java, it must be consistent across execution sessions and it can return a long.
I will be hashing directory names / strings. This should work so that "somefolder1"
and "somefolder2"
will return different hashes, as would "JJK"
and "JJL"
. I'd also like some idea of when clashes are likely to occur.
Any suggestions?
Thanks
发布评论
评论(4)
好吧,几乎所有散列函数都具有输入的微小变化会导致输出发生较大变化的属性,这意味着“somefolder1”和“somefolder2”将始终产生不同的散列。
至于冲突,看哈希输出有多大就可以了。 Java 自己的
hashcode()
返回一个int
,因此您可能会比 MD5 或 SHA- 1,例如,分别产生 128 和 160 位。不过,您不应该尝试从头开始创建这样的函数。
但是,我不太明白您的用例是否不应该发生冲突,或者如果很少发生冲突是否可以接受。对于链接文件夹,我肯定会使用保证唯一的标识符,而不是可能多次出现的标识符。
Well, nearly all hashing functions have the property that small changes in the input yield large changes in the output, meaning that "somefolder1" and "somefolder2" will always yield a different hash.
As for clashes, just look at how large the hash output is. Java's own
hashcode()
returns anint
, therefore you can expect clashes more often than with MD5 or SHA-1, for example which yield 128 and 160 bit, respectively.You shouldn't try creating such a function from scratch, though.
However, I didn't quite understand whether collisions shouldn't ever occur with your use case or whether they are acceptable if rare. For linking folders I'd definitely use a guarenteed-to-be-unique identifier instead of something that might occur more than once.
您没有描述在什么情况下不同字符串应该返回相同哈希值。
一般来说,我会通过首先实现相等函数来设计哈希函数。这应该会告诉你哪些数据位需要包含在哈希中,哪些数据位应该被丢弃。如果两个不同数据位之间的相等性很复杂(例如不区分大小写),那么希望有一个相应的哈希函数用于该特定比较。
无论你做什么,都不要假设相等的哈希值意味着相等的键(即哈希值是唯一的)——这始终是潜在问题的原因。
You haven't described under what circumstances different strings should return the same hash.
In general, I would approach designing a hashing function by first implementing the equality function. That should show you which bits of data you need to include in the hash, and which should be discarded. If the equality between two different bits of data is complicated (e.g. case-insensitivity) then hopefully there will be a corresponding hash function for that particular comparison.
Whatever you do, don't assume that equal hashes mean equal keys (i.e. that hashing is unique) - that's always a cause of potential problems.
Java 的 String hashcode 会给你一个
int
,如果你想要一个long
,你可以取 String 的 MD5 和的最低有效 64 位。可能会发生冲突,您的系统必须为此做好准备。也许如果您更详细地说明哈希码的用途,我们就可以看到冲突是否会导致问题。
Java's String hashcode will give you an
int
, if you want along
, you could take the least-significant 64 bits of the MD5 sum for the String.Collisions could occur, your system must be prepared for that. Maybe if you give a little more detail as to what the hash codes will be used for, we can see if collisions would cause problems or not.
时,在 N 个哈希之后发生冲突的几率为 50%
对于具有 M 个可能值的均匀随机哈希函数,当查找 生日问题以进行更多分析。
如果您提前知道所有密钥,则可以使用完美哈希来避免冲突。
With a uniformly random hash function with M possible values, the odds of a collision happening after N hashes are 50% when
Look up the birthday problem for more analysis.
You can avoid collisions if you know all your keys in advance, using perfect hashing.