在 16 字节短消息上使用 CRC32

问题描述

我想在一条短消息(16 字节)上使用 CRC32 作为唯一密钥用于其他目的。对于每个可能的 16 字节消息,是否可以保证 CRC32 值是唯一的? 鉴于可以有 2^128 条消息(或超过 3.40 × 10^38,如果您愿意) 无法在电子表格上进行测试。

解决方法

没有。 CRC32 是 32 位,因此无法将 128 位唯一地映射到 32 位。

校验和函数(如 CRC32)可用于检测常见损坏(如更改了一个字节),而不是用于唯一标识。

接近函数是散列函数,它试图为每个输入赋予唯一的值,但它们不保证没有冲突,只是尝试最小化典型输入分布的概率。

还有“完美散列函数”可以保证是唯一的,但它将输入集限制为散列函数输出范围,并且通常以查找表的形式实现。

,

您不需要测试所有 2^128 种可能的模式。对于 128 位数据,最好的 32 位 CRC 多项式最多可以检测 7 位错误。

https://users.ece.cmu.edu/~koopman/crc/crc32.html

一般来说,这些 7 位错误检测 CRC 最多只能纠正 3 位错误,因此有一些 4 位模式会产生重复。一个测试程序只需要测试 comb(128,4) = 10,668,000 个模式来搜索 4 位模式之间的重复项。 4 位模式不能复制 1、2 或 3 位模式,因为最坏的情况是总共 7 个错误位,这些 CRC 保证能够检测到。

我使用 CRC 多项式 0x1f1922815 进行了测试,除了要测试的模式外全为零位,并且发现的第一个冲突发生在这两个 4 位模式之间:

import requests


def main(url):
    params = {
        "x-algolia-agent": "Algolia for JavaScript (3.35.1); Browser","x-algolia-application-id": "JF8Q26WWUD","x-algolia-api-key": "ecef10153e66bbd6d54f08ea005b60fc"
    }
    data = "{\"requests\":[{\"indexName\":\"vnw_job_v2\",\"params\":\"query=&hitsPerPage=1000&attributesToRetrieve=%5B%22*%22%2C%22-jobRequirement%22%2C%22-jobDescription%22%5D&attributesToHighlight=%5B%5D&query=&facetFilters=%5B%5D&filters=&numericFilters=%5B%5D&page=0&restrictSearchableAttributes=%5B%22jobTitle%22%2C%22skills%22%2C%22company%22%5D\"}]}"

    r = requests.post(url,params=params,data=data)
    for item in r.json()['results'][0]['hits']:
        print(item['jobTitle'])


if __name__ == "__main__":
    main('https://jf8q26wwud-dsn.algolia.net/1/indexes/*/queries')