c++;字符串需要唯一ID,但无论顺序如何,始终相同 我需要一个唯一的ID,用于读取一个C++程序的文档,它将被载入数据库。不管其绑定的文档是先通过程序自己运行还是在其他文档堆栈中运行,ID必须是相同的。这样我就可以允许数据库中的文档被覆盖

c++;字符串需要唯一ID,但无论顺序如何,始终相同 我需要一个唯一的ID,用于读取一个C++程序的文档,它将被载入数据库。不管其绑定的文档是先通过程序自己运行还是在其他文档堆栈中运行,ID必须是相同的。这样我就可以允许数据库中的文档被覆盖,c++,ascii,unique,document,C++,Ascii,Unique,Document,我考虑使用文档名的ASCII值,例如 员工规范第358页 但它的价值与 回答警告.doc 358 这意味着当我在程序中运行第二个文档时,它会覆盖第一个文档的存在 ID必须是一个数字,并且必须是唯一的,但它必须是一致的可重新生成的,而不必交叉引用数据库本身(因为此程序与数据库导入程序分开运行) 希望有人有一些想法,因为我被难住了 编辑:我尝试使用MD5转换“Employee Spec Page.doc”和“Answer Warnings.doc”,得到了以下字符表示形式: 回答警告:2DCB250

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

员工规范第358页

但它的价值与

回答警告.doc 358

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

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

希望有人有一些想法,因为我被难住了

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

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

但是,当我将char*转换为无符号int

char* docID = md5.digestString(pDocument->m_csDocumentName.GetBuffer());
pDocument->m_csDocID.Format("%i",(unsigned int)docID);
我觉得这两个都是:

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

我从这里得到了md5课程:


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

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

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

您需要的是一个生成足够大的数字以避免冲突的函数。(如上所述)应该可以

只需截断MD5结果,就可以生成更短的键。但是要注意,你增加了碰撞的机会。128位具有超过10^38个不同的密钥;64位有10^19以上;32位的大小超过10^9(4.294.967.296)。因此,32位几乎有可能在两个特定文档之间发生冲突。对于10000个文档,您有1%的几率至少发生一次冲突。是否接受某个密钥长度取决于您的要求。当然,您可以实现冲突检测和冲突解决

如果“数据库”只允许短键,则必须实现冲突解决。要了解如何做到这一点,请参见

从:'10^−18至10^−15是典型硬盘的不可纠正误码率。理论上,MD5散列或UUID(128位)应该保持在这个范围内,直到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;

您需要的是一个生成足够大的数字以避免冲突的函数。(如上所述)应该可以

只需截断MD5结果,就可以生成更短的键。但是要注意,你增加了碰撞的机会。128位具有超过10^38个不同的密钥;64位有10^19以上;32位的大小超过10^9(4.294.967.296)。因此,32位几乎有可能在两个特定文档之间发生冲突。对于10000个文档,您有1%的几率至少发生一次冲突。是否接受某个密钥长度取决于您的要求。当然,您可以实现冲突检测和冲突解决

如果“数据库”只允许短键,则必须实现冲突解决。要了解如何做到这一点,请参见

从:'10^−18至10^−15是典型硬盘的不可纠正误码率。理论上,MD5散列或UUID(128位)应该保持在这个范围内,直到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;


这还不错,但如果我使用md5将每个字符转换为一个十六进制字符串,然后将这些字符转换回整数,它会给我一个非常非常长的整数。有没有办法使它唯一,并且仍然不超过5个字符?没有奇迹-如果你使用一个较短的哈希函数,例如CRC,冲突将更有可能。另一种可能是简单地将所有名称存储在一个表中,并为它们分配递增的数字,但您需要维护该表,并且必须始终拥有该表才能找到id。MD5提供128位。这足以避免在规模合理的问题上发生冲突。128位是16字节或32个十六进制字符。这还不错,但如果我使用md5将每个字符转换为一个十六进制字符串,然后将这些字符转换回整数,它会给我一个非常非常长的整数。有没有办法使它唯一,并且仍然不超过5个字符?没有奇迹-如果你使用一个较短的哈希函数,例如CRC,冲突将更有可能。另一种可能是简单地将所有名称存储在一个表中,并为它们分配递增的数字,但您需要维护该表,并且必须始终拥有该表才能找到id。MD5提供128位。这足以避免在规模合理的问题上发生冲突。128位是16字节或32个十六进制字符。您不能像这样将
char*
协调到
int
并期望在不同的运行中得到相同的结果。您得到的是一个int,它取决于哈希在内存中的存储位置,而不是哈希函数的值。您不能从指针类型强制转换为非指针类型,并期望发生任何合理的情况。public://MD5摘要是一个16字节的数字(32十六进制数字)byte digestRaw[16];//这个版本的摘要实际上是//一个“printf'd”版本的摘要。char-digestschars[33];因为我不能在家里做格式化