Java 为给定的唯一编号列表/集合/数组生成唯一id
我的数组包含从0到integer.max value的随机唯一数 如何生成唯一的id/签名(int)来唯一地标识每个数组,而不是搜索每个数组并检查每个数字 e、 g 每个数组可以有不同的长度,但数字在数组中不重复,可以在其他数组中重复。每个数组的唯一id的目的是通过id来识别它,以便快速进行搜索。数组包含组件的id,数组的唯一签名/id将标识其中包含的组件 此外,无论数组中值的顺序如何,生成的id都应该相同。像{1,5}和{5,1}应该生成相同的id 我查找了不同的数字配对方法,但结果数字随着数组长度的增加而增加,达到了整数无法容纳的程度Java 为给定的唯一编号列表/集合/数组生成唯一id,java,encryption,cryptography,wolfram-mathematica,Java,Encryption,Cryptography,Wolfram Mathematica,我的数组包含从0到integer.max value的随机唯一数 如何生成唯一的id/签名(int)来唯一地标识每个数组,而不是搜索每个数组并检查每个数字 e、 g 每个数组可以有不同的长度,但数字在数组中不重复,可以在其他数组中重复。每个数组的唯一id的目的是通过id来识别它,以便快速进行搜索。数组包含组件的id,数组的唯一签名/id将标识其中包含的组件 此外,无论数组中值的顺序如何,生成的id都应该相同。像{1,5}和{5,1}应该生成相同的id 我查找了不同的数字配对方法,但结果数字随着数
分配给组件的ID可以调整,它们不必是整数序列,只要有一个良好的数字范围就可以。唯一的要求是,一旦为数组(组件id的集合)生成了id,它们就不应该冲突。如果该数组中的集合发生更改,则可以在运行时生成。严格来说,您要求的是不可能的:即使只有两个元素的数组,可能的数组(忽略顺序后约261个)也比可能的签名(232个)多得多。而且您的数组不限于两个元素,因此您的情况会成倍恶化
但是,如果您可以接受低重复率和错误匹配率,一种简单的方法是使用
+
运算符将所有元素相加(基本上计算模232的和)。这是java.util.Set的hashCode()方法所采用的方法。它并不能完全消除比较整个数组的需要(因为需要检测错误的匹配),但它将从根本上减少这种比较的数量(因为很少有数组会匹配任何给定的数组)。这可以通过哈希函数h()
和顺序规范化函数近似解决(例如sort()
)。散列函数是有损的,因为唯一散列(2^32或2^64)的数量小于可能的可变长度整数集的数量,导致两个不同的集合具有相同ID的可能性很小(散列冲突)。通常,如果
- 你使用了一个好的散列函数
- 您的数据集并没有大到可笑的程度
int getId(setOfInts) {
intList = convert setOfInts to integer list
sortedIntList = sort(intList)
ilBytes = cast sortedIntList to byte array
hashdigest = hash(ilBytes)
leadingBytes = extract 4 or 8 leading bytes of hashdigest
idInt = cast leadingBytes to integer
return idInt
}
您希望{1,5}和{5,1}具有相同的ID。这排除了标准哈希函数,在这种情况下,标准哈希函数将给出不同的结果。一个选项是在哈希之前对数组进行排序。请注意,加密哈希非常慢;您可能会发现像FNV这样的非加密哈希就足够了。它肯定会更快
为了避免排序,只需添加mod 2^32或mod 2^64的所有数字,正如@ruakh所建议的,并接受您将有一定比例的冲突。添加数组长度将避免一些冲突:{5,1}将不匹配{1,2,3},在这种情况下为(2+(5+1))!=(3+(1+2+3))。您可能希望使用实际数据进行测试,以查看这是否具有足够的优势。发布您迄今为止尝试过的代码。您希望此id确切位置在何处?如果您希望它出现在数组中,您可以开始添加负数作为第一个数字(例如,第一个数组有-1,第二个数组有-2等等)
int getId(setOfInts) {
intList = convert setOfInts to integer list
sortedIntList = sort(intList)
ilBytes = cast sortedIntList to byte array
hashdigest = hash(ilBytes)
leadingBytes = extract 4 or 8 leading bytes of hashdigest
idInt = cast leadingBytes to integer
return idInt
}