php - CRC-32 是否保证生成 40 亿个唯一值?
问题描述
我只想知道对于 CRC32 哈希函数,特别是 PHPcrc
函数,我是否会为输入值(整数)获得 2^32(40 亿)个不同的值,保证从 1 到 40 亿按顺序递增?
解决方案
我不认为 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 位整数转换为唯一的伪随机值,有很多更有效的方法可以做到这一点。例如,考虑使用线性同余生成器。
推荐阅读
- javascript - 如何 Lodash groupBy 并按日期和时间排序
- php - 来自存储库的查询返回语义错误 - 不知道为什么
- graphql - 是否可以将 quarkus 安全性与 quarkus-smallrye-graphql 一起使用?
- amazon-web-services - 如何在 AWS CloudFront 重定向 URL?
- javascript - Uncaught SyntaxError: missing ) 在完全正确的东西的参数列表之后
- javascript - JavaScript Promises:如何使用调用堆栈和任务队列实现承诺?
- laravel - 如何在 Laravel Shopify 应用程序中解决 x-frame-options 到 'sameorigin' 的问题
- symfony4 - 是否有 ChoiceType 允许用户从 Symfony 的选项列表中仅选择一个选项?
- javascript - 如何从选项列表中计算价格?
- python-2.7 - python脚本除以零失败