散列图像(rgb字节系列)

时间:2014-07-18 22:59:32

标签: c++ winapi hash

我正在开发一个涉及使用C / C ++进行屏幕捕获和散列的应用程序。我捕获的图像尺寸大约为 250x250 ,我正在使用winapi HashData 函数进行散列。

我的目标是比较2个哈希值(等于2张250x250的图像)并立即判断它们是否相等。

我的代码:

           const int PIXEL_SIZE = (sc_part.height * sc_part.width)*3;
           BYTE* pixels = new BYTE[PIXEL_SIZE];
           for(UINT y=0,b=0;y<sc_part.height;y++) {
              for(UINT x=0;x<sc_part.width;x++) {
                 COLORREF rgb = sc_part.pixels[(y*sc_part.width)+x];
                 pixels[b++] = GetRValue(rgb);
                 pixels[b++] = GetGValue(rgb);
                 pixels[b++] = GetBValue(rgb);
              }
           }
           const int MAX_HASH_LEN = 64;
           BYTE Hash[MAX_HASH_LEN] = {0};
           HashData(pixels,PIXEL_SIZE,Hash,MAX_HASH_LEN);

           ... i have now my variable-size hash, above example uses 64 bytes

           delete[] pixels;

我已经测试了不同的哈希大小及其完成时间,大约是:

           32 bytes  = ~30ms
           64 bytes  = ~47ms
           128 bytes = ~65ms
           256 bytes = ~125ms

我的问题是:

对于250x250图像,哈希码需要多长时间来防止任何重复,例如从来没有?

我不喜欢 256 字符的哈希码,因为它会导致我的应用程序运行缓慢(因为捕获非常频繁)。每个图像维度是否有"safe"哈希大小用于比较?

感谢名单

2 个答案:

答案 0 :(得分:2)

根据您的评论,假设您正在添加计算出的哈希值&#34;即时&#34;到数据库,所以数据库中每个图像的散列最终都会与数据库中每个其他图像的散列进行比较,然后你就会遇到birthday paradox。在一组随机选择的数字(例如,一群人的生日)中存在两个相同数字的可能性大于您直觉假设的数字。如果一个房间里有23个人,那么50:50的机会中有两个人共享同一个生日。

这意味着假设一个好的散列函数然后你可以预料到一个碰撞,两个图像具有相同的散列,尽管不相同,在2 ^(N / 2)个散列之后,其中N是散列中的数字位。{{ 3}}如果你的哈希函数不是那么好,你甚至可以更早地发现碰撞。不幸的是,只有微软知道HashData实际上有多好。

你的意见也提出了其他一些问题。一个是HashData没有产生可变大小的哈希值。它生成一个字节数组,其长度始终与您作为哈希长度传递的值相同。您的问题是您将其视为一串字符。在C ++中,字符串是零终止的,这意味着字符串的结尾标有零值字符('\0')。由于字节数组将在随机位置包含0个有价值的元素,因此在使用字符串时它似乎会被截断。像这样处理散列字符串会使你更容易发生碰撞。

另一个问题是,您说您在数据库中存储了要比较的图像,并且这些图像必须是唯一的。如果数据库强制执行此唯一性,那么在您自己的代码中检查唯一性是多余的。您的数据库可能比您自己的代码更快地执行此操作。

答案 1 :(得分:0)

GUID(全局唯一ID)长度为16个字节,Microsoft假定不会发生任何GUID冲突。

使用32字节散列相当于获取两个随机生成的GUID,并将它们与其他两个随机生成的GUID进行比较。

可能性很小(1/2 ^ 256)或1.15792089E-77,您将与32字节哈希发生冲突。

宇宙在你发生碰撞之前很久就会死亡。

Michael Grier的

This comment或多或少地囊括了我的信念。在最坏的情况下,您应该拍摄图像,计算哈希值,将图像更改1个字节,然后重新计算哈希值。一个好的哈希应该改变多个字节。

你还需要将其与“生日效应”(也称为鸽子原则)进行交换 - 任何哈希都会产生碰撞。但是,对前N个字节的快速比较通常会拒绝冲突。

加密散列通常是“更好”的散列,因为每个输入位更改会有更多的散列位更改,但计算速度要慢得多。