c ++需要字符串的唯一ID,但无论顺序如何都始终相同

时间:2012-12-01 17:40:16

标签: c++ ascii unique document

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

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

员工规范Page.doc 358

但它与

具有相同的值

回答Warnings.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存储在数据库中。

2 个答案:

答案 0 :(得分:3)

你需要的是一个hash函数,它产生一个足以避免碰撞的数字。 MD5(正如上面提到的piokuc)应该没问题

只需截断MD5结果即可生成更短的密钥。但请注意,您增加了碰撞的机会。 128位有超过10 ^ 38个不同的键; 64位超过10 ^ 19; 32位超过10 ^ 9(4.294.967.296)。所以32位接近两个特定文件之间发生冲突的抽奖机会。对于10.000份文件,您至少有一次碰撞有1%的可能性。接受某个密钥长度取决于您的要求。你当然可以实现碰撞检测和碰撞解决。

如果您的'数据库'只允许短键,则必须实现冲突解决。有关如何操作的想法,请参阅Hash_table Collision_resolution

来自Wikipedia:'10 ^ -18到10 ^ -15是典型硬盘的无法纠正的误码率。从理论上讲,MD5哈希值或UUID(128位)应该保持在该范围内,直到大约820亿个文档“


到你的具体图书馆:

如果查看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;

答案 1 :(得分:2)

您可以使用md5算法生成ID,您可以轻松找到免费的实现。