我试图了解 crc32 以生成网页的唯一 url。
如果我们使用 crc32,为了避免重复,最多可以使用多少个 url?
保持校验和为 2^32 的近似字符串长度是多少?
当我尝试将 UUID 用于 url 并将 uuid 字节转换为 base 64 时,我可以减少到 22 个字符的长度。我不知道我可以进一步减少。
大多数情况下,我想将 url(最多 1024 个字符)转换为短 id。
CRC32 没有“可以使用的最大 url 数,以避免重复”这样的数字。
问题是 CRC32 可以产生重复,它不是你扔给它多少值的函数,而是这些值看起来像什么的函数。
因此,如果您不走运,您可能会在第二个 url 上发生冲突。
您不应将算法建立在生成唯一哈希的基础上,而应手动为每个 url 生成唯一值。
如果您已经将完整的 URL 存储在数据库表中,则整数 ID 非常短,可以通过将其转换为基数 16、64 或 85 来缩短。如果可以使用 UUID,则可以使用整数,你也可以,因为它更短,而且我看不出 UUID 会在你的查找表中提供什么好处。
制作短 URL 的正确方法是将完整的 URL 存储在数据库中并发布映射到行索引的内容。例如,一种紧凑的方法是使用行 ID 的 Base64。或者您可以使用 UID 作为主键并显示它。
不要使用校验和,因为它太小并且很可能发生冲突。加密哈希更大且可能性更小,但这仍然不是正确的方法。
CRC32 表示具有 32 位的循环冗余校验,其中任意数量的位总和为 32 位校验和。并且校验和函数是满射的,这意味着多个输入值具有相同的输出值。所以你不能反转这个函数。
不,即使您使用 md5 或任何其他校验和,URL 也可能重复,这完全取决于您的运气。
所以不要根据这些校验和创建一个唯一的 url
解决问题的最快(也许是最好的!)方法可能是简单地使用本地路径的哈希和给定 URI 的查询,如下所示:
using System;
namespace HashSample
{
class Program
{
static void Main(string[] args)
{
Uri uri = new Uri(
"http://host.com/folder/file.jpg?code=ABC123");
string hash = GetPathAndQueryHash(uri);
Console.WriteLine(hash);
}
public static string GetPathAndQueryHash(Uri uri)
{
return uri.PathAndQuery.GetHashCode().ToString();
}
}
}
以上假设 URI 方案和主机保持不变。如果不是 GetHashCode 将适用于任何字符串。
有关 CRC32 哈希冲突的精彩讨论,请访问:http ://episteme.arstechnica.com/eve/forums/a/tpc/f/6330927813/m/821008399831