是否可以确保CRC-32产生40亿个唯一值?

时间:2019-06-25 07:59:48

标签: php hash cryptography crc32

我只想知道CRC32哈希函数,特别是PHP crc函数,对于输入值(整数),我将得到2 ^ 32(40亿)个不同的值,保证可以按顺序递增从1到40亿?

2 个答案:

答案 0 :(得分:1)

我认为CRC32并不是专门为所有可能的四字节输入而设计的。但是,它似乎确实可以这样工作。您只需检查所有可能的输出即可自己验证。为了加快速度,我使用了以下C程序:

/* Compile: cc crc_check.c -O3 -lz -o crc_check */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <zlib.h>

int main() {
    uint32_t x, y, d;
    uint64_t i, *seen, mask;

    seen = calloc(0x4000000, 8);
    if (!seen) return -1;

    /* Make sure we're calculating the same values as PHP's crc32 function */
    printf("crc32(\"ABCD\") = %lu\n", crc32(0, (unsigned char*)"ABCD", 4));

    for (i=x=0; i<0x100000000ULL; i++) {
        y = crc32(0, (unsigned char*)(&x), 4);
        mask = 1ULL << (y & 0x003fULL);
        d = y >> 6;
        if (seen[d] & mask) {
            printf("Collision detected (x=%u, y=%u)\n", x, y);
            return 0;
        }
        seen[d] |= mask;
        x++;
    }
    puts("No collisions detected");
    return 0;
}

/*
   Output:
   crc32("ABCD") = 3675725989
   No collisions detected
*/

只是为了确保zlib使用相同的功能,我添加了一行来输出字符串“ ABCD”的CRC32校验和。 PHP产生相同的值:

$ php -r 'echo crc32("ABCD");'
3675725989

不过,我不得不问:您需要这些信息做什么?如果要将连续的32位整数转换为唯一的伪随机值,则可以使用更有效的方法。例如,考虑使用linear congruential generator

答案 1 :(得分:0)

CRC产生错误的哈希函数。这是一篇有关该主题的简洁文章:https://eklitzke.org/crcs-vs-hash-functions