我需要为 Mysql 表中的每一行分配一个随机但唯一的 ID。如果该行包含相同的值,则 ID 应该相同。
即,如果第 1 行包含 [hi,hello,bye] 第 2 行包含 [gg,hello,bye] 并且第 3 行包含 [hi,hello,bye] 那么第 1 行和第 3 行应该生成相同的 ID 并且第 2 行应该生成不同的身份证。
提前致谢。
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
SELECT CRC32(CONCAT(column1, column2, column3)) FROM MyTable.
从技术上讲,CRC32 不是随机的(但什么是随机的?)——它产生冲突的可能性很小(不同的值映射到同一个整数)。但这是一个开始。
如果你真的想要证明你没有发生冲突,那么一切都归结为连接所有字段,字段中不包含分隔符。当然,这通常会很长而且很麻烦。
每个人通常做的是:在哈希函数中输入该字符串。虽然理论上不是唯一的,但给定一个具有足够大结果的合适哈希函数,应该能够找到一个在人类生存期间不太可能产生碰撞的哈希函数。例如 git 正在使用这样的哈希 (sha1) 并且 Linus Torvalds 写了关于意外碰撞的机会:
首先,让我提醒人们,这种无意的碰撞真的非常非常不可能,所以我们很可能永远不会在整个宇宙历史中看到它。
不同的事情是不那么偶然的碰撞。首先,您应该确保您开始的字符串对于不同的列是不同的。这表示:
如果您必须担心有针对性的攻击,即有人实际上试图创建具有相同哈希的条目,那么您最好的选择是使用加密哈希,可能用于密码哈希的密码哈希通常设计得很慢,以防止暴力破解强制攻击。当然,这可能与大多数应用程序尽可能快的要求相冲突。