我需要为Mysql表中的每一行分配一个随机但唯一的ID。如果该行包含相同的值,则ID应相同。
即。如果第1行包含[hi,hello,bye]第2行包含[gg,hello,bye],第3行包含[hi,hello,bye],则第1行和第3行应生成相同的ID和第2行行应该生成不同的ID。
提前致谢。
答案 0 :(得分:3)
MD5哈希可以工作。下面是需要更新的快速/脏代码,但证明了这个概念。
System.out.println("row1=" + test1 + ":" + tst1.getHash(test1));
System.out.println("row2=" + test2 + ":" + tst1.getHash(test2));
System.out.println("row3=" + test3 + ":" + tst1.getHash(test3));
private String getHash(String inputStr){
try{
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(inputStr.getBytes());
byte byteData[] = md.digest();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < byteData.length; i++) {
sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
}
return sb.toString();
}
catch(Exception e)
{
e.printStackTrace();
return null;
}
}
row1=hi,hello,bye:cfe40e96aa052a484208c2aefb6f39bb
row2=gg,hello,bye:f652785f0e214507e6aea44ecd3ffb7a
row3=hi,hello,bye:cfe40e96aa052a484208c2aefb6f39bb
答案 1 :(得分:1)
SELECT CRC32(CONCAT(column1, column2, column3)) FROM MyTable.
从技术上讲,CRC32不是 random (但它是什么?) - 它产生冲突的可能性很小(不同的值映射到同一个整数)。但这是一个开始。
答案 2 :(得分:0)
如果你真的想要证明你没有发生碰撞,那么一切都归结为连续所有领域,并且字段中没有包含分隔符。当然,这通常会很长很麻烦。
每个人通常做的是:在Hash函数中输入String。虽然理论上并不是唯一的,但是如果合适的Hash函数具有足够大的结果,那么应该能够找到一个在人类生命期间不太可能产生碰撞的函数。例如,git使用这样的哈希(sha1),Linus Torvalds写了chance of a accidental collision:
首先,让我提醒人们无意中的那种 碰撞真的真的真的该死的不太可能,所以我们会相当的 可能永远不会在宇宙的整个历史中看到它。
另一件事是不是偶然的碰撞。首先,您应该确保您开头的字符串对于不同的列不一样。这意味着:
如果你不得不担心有针对性的攻击,即有人试图创建具有相同哈希的条目,最好的办法是使用加密哈希,可能是一个用于密码哈希的哈希,它通常设计得很慢,按顺序排列防止蛮力攻击。当然,这可能会与大多数应用程序的要求相冲突。
答案 3 :(得分:0)
您需要的是您连续关注的所有值的hash function。它不能是随机的,因为根据定义,它必须是确定性的 - 给定相同的值,您总是得到相同的ID。如果,“随机”,你的意思是“不顺序”,大多数哈希函数应该满足这种需要。
理论上,你无法保证唯一性,因为始终存在碰撞的可能性。也就是说,不同的ID肯定意味着行值不同,但反过来并不总是正确的。根据您的需要,您可能希望在遇到匹配ID时在实际行值上实现显式匹配。你也可以考虑使用类似MD5或SHA1的cryptographic hash function并依赖于你身边的概率(实际上,你使用加密哈希函数找到的任何碰撞都会在现场取得某种突破)。 / p>