4

我需要为 Mysql 表中的每一行分配一个随机但唯一的 ID。如果该行包含相同的值,则 ID 应该相同。

即,如果第 1 行包含 [hi,hello,bye] 第 2 行包含 [gg,hello,bye] 并且第 3 行包含 [hi,hello,bye] 那么第 1 行和第 3 行应该生成相同的 ID 并且第 2 行应该生成不同的身份证。

提前致谢。

4

4 回答 4

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
于 2013-03-05T05:31:23.427 回答
1
SELECT CRC32(CONCAT(column1, column2, column3)) FROM MyTable.

从技术上讲,CRC32 不是随机的(但什么是随机的?)——它产生冲突的可能性很小(不同的值映射到同一个整数)。但这是一个开始。

于 2013-03-05T05:19:06.303 回答
0

你需要的是一个你关心的所有值的哈希函数。它不能是随机的,因为根据定义,它必须是确定性的——给定相同的值,你总是得到相同的 ID。如果“随机”是指“非连续”,则大多数散列函数应该满足这种需求。

从理论上讲,您不能保证唯一性,因为总是存在冲突的可能性。也就是说,不同的 ID 肯定意味着行值不同,但反过来并不总是正确的。根据您的需要,您可能希望在遇到匹配 ID 时对实际行值实施显式匹配。您也可以考虑使用像 MD5 或 SHA1 这样的加密散列函数,并依赖于您身边的概率(事实上,使用加密散列函数发现的任何冲突都将是该领域的某种突破)。

于 2013-03-05T06:07:23.990 回答
0

如果你真的想要证明你没有发生冲突,那么一切都归结为连接所有字段,字段中不包含分隔符。当然,这通常会很长而且很麻烦。

每个人通常做的是:在哈希函数中输入该字符串。虽然理论上不是唯一的,但给定一个具有足够大结果的合适哈希函数,应该能够找到一个在人类生存期间不太可能产生碰撞的哈希函数。例如 git 正在使用这样的哈希 (sha1) 并且 Linus Torvalds 写了关于意外碰撞的机会

首先,让我提醒人们,这种无意的碰撞真的非常非常不可能,所以我们很可能永远不会在整个宇宙历史中看到它。

不同的事情是不那么偶然的碰撞。首先,您应该确保您开始的字符串对于不同的列是不同的。这表示:

  • 确保包含所有列
  • 确保列 a 由列本身中不包含的内容分隔。必要时使用转义。例如,如果您只是连接两列,则值 'abc' + 'def' 将给出与 'a' + 'bcdef' 相同的结果

如果您必须担心有针对性的攻击,即有人实际上试图创建具有相同哈希的条目,那么您最好的选择是使用加密哈希,可能用于密码哈希的密码哈希通常设计得很慢,以防止暴力破解强制攻击。当然,这可能与大多数应用程序尽可能快的要求相冲突。

于 2013-03-05T06:05:27.097 回答