1

我需要一个唯一的 ID 用于读入 c++ 程序的文档,该程序将携带到数据库中。无论它所绑定的文档是首先通过程序运行、单独运行还是在一堆其他文档的中间运行,ID 都需要相同。这样我就可以尊重数据库中文档的覆盖。

我考虑使用文档名称的 ASCII 值,例如

员工规格页面.doc 358

但它具有相同的价值

回答警告.doc 358

这意味着当我在程序中运行第二个文档时,它会覆盖第一个文档的存在。

ID 必须是一个数字并且必须是唯一的,但它必须始终可以重新生成,而不必交叉引用数据库本身(因为该程序与数据库导入程序分开运行)

希望有人有一些想法,因为我很难过。

编辑:我尝试使用 MD5 转换“Employee Spec Page.doc”和“Answer Warnings.doc”并得到以下字符表示:

回答警告:2dcb2503c48f5472bfdbafe28d565a9d
员工规格页面:a9be4c1428c11b406072c0bd3dab2dee

但是,当我将 char* 转换为 unsigned int

char* docID = md5.digestString(pDocument->m_csDocumentName.GetBuffer());
pDocument->m_csDocID.Format("%i",(unsigned int)docID);

我得到两者都是:

回答警告:1634456
员工规格页面:1634456

我从这里得到了 md5 类:http: //bobobobo.wordpress.com/2010/10/17/md5-c-implementation/

我究竟做错了什么?我需要它是一个整数,否则我将无法将 ID 存储在数据库中。

4

2 回答 2

3

您需要的是一个散列函数,该函数生成一个足够大的数字以避免冲突。MD5(如上面提到的 piokuc)应该没问题

您可以通过简单地截断 MD5 结果来生成更短的密钥。但请注意,您会增加发生碰撞的机会。128 位有超过 10^38 个不同的密钥;64位有超过10^19;32 位有超过 10^9 (4.294.967.296)。所以 32 位几乎有机会在两个特定文档之间发生冲突。对于 10.000 个文档,您有 1% 的机会至少发生一次冲突。接受某个密钥长度取决于您的要求。您当然可以实现碰撞检测和碰撞解决。

如果您的“数据库”仅允许使用短键,则您必须实施冲突解决方案。有关如何做到这一点的想法,请参阅Hash_table Collision_resolution

来自维基百科:'10^-18 到 10^-15 是典型硬盘的不可纠正误码率。理论上,128 位的 MD5 哈希或 UUID 应该保持在该范围内,直到大约 8200 亿个文档'


到您的具体库:

如果你查看 md5 头文件,有

public:
    // an MD5 digest is a 16-byte number (32 hex digits)
    BYTE digestRaw[ 16 ] ;

因此您可以随时检索二进制摘要

MD5 md5;
char* docID = md5.digestString(pDocument->m_csDocumentName.GetBuffer());
unsigned int hash_ui = *(unsigned int *)digestRaw;

于 2012-12-01T17:52:24.777 回答
2

您可以使用 md5 算法生成 id,您会很容易找到一个免费的实现。

于 2012-12-01T17:45:25.413 回答