我需要一个唯一的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存储在数据库中。
答案 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,您可以轻松找到免费的实现。