7

我想唯一地缩短字符串文件 id 以在 url 中使用,如 bit.ly 等。我可以使用 db 中的 id,但我希望 url 是随机的。

什么是最好的解决方案?

网站将是一个移动网站,所以我希望它尽可能短

4

5 回答 5

6

有两种方法可以实现您所描述的映射服务。

  1. 客户提交全球唯一的 ID,或
  2. 服务器生成全局唯一 ID

客户提交全球唯一的 id

据我所知,1. 只能尝试使用Guids,除非您设计了类似的方法将足够不同的信息塞入短字节流中。无论哪种方式,如果你有一个代表全局唯一标识符的字节流,你可以做这样的事情

// source is either a Guid, or some other globally unique byte stream
byte[] bytes = Guid.NewGuid ().ToByteArray ();
string base64String = Convert.ToBase64String (bytes).Trim ("=");

获得一个用户可读的字母数字字符串,它看起来是随机的,但避免了其他随机方案中固有的冲突。AGuid包含 16 个字节或 128 位,对于完整的 Base64 编码,它转换为大约 19 个字符。

这种方法的优点是客户端可以在没有中央权限的情况下生成自己的微型 Uris。不利的一面是,如果您使用Guid,或者实现自己的全局唯一字节流(让我们面对现实),它很容易出错。

如果您确实走这条路,请考虑使用 Google 搜索全球唯一的字节流等。哦,远离随机字节,否则你将不得不在你的微型 Uri 生成器上构建碰撞解决方案。

服务器生成全局唯一 ID

同样,上述的主要优点是客户可以先验地生成他们的 Uris 。如果您要提交一个您希望检查的长期运行的请求,则特别方便。这可能与您的情况并不特别相关,并且可能仅提供有限的价值。

因此,除此之外,以服务器为中心的方法(其中单个权限生成并分发 ID)可能更具吸引力。如果这是您选择的路线,那么唯一的问题是您希望您的 Uri 多久?

假设所需长度为 5 个字符,假设您使用 Base64 编码,每个 id 最多可以表示 5 个字符,每个字符 7 位等于 35 位或 2^35 [34 359 738 368] 个不同的值。这是一个相当大的域。*

然后它变成了为给定提交返回值的问题。可能有很多方法可以做到这一点,但我会选择这样的方法,

  • 枚举数据库中“空闲列表”中的所有可能值
  • 消耗时从空闲列表中删除值
  • 释放时为空闲列表增加价值

增强或优化可能包括

  • 不要枚举范围 [0, 2^35] 上的每个值,而是枚举一个可管理的子集,例如一次 100 000 个值,当所有值都用完后,只需依次生成另外 100 000 个值并继续
  • 为值添加到期日期,并在一天结束时回收到期的值
  • 分发您的服务,在并行化您的服务时,只需将空闲列表中相互排斥的小子集分配给分布式服务

结论

底线是,你想保证唯一性——所以碰撞是一个很大的禁忌。


*=34 359 738 368 是原始域的大小,这是所有长度为 0 到 5 的 id。如果您有兴趣将所有 id 限制为最小和最大 5 长度,那么您的域看起来像所有长度为 0 到 5 (2^35) 的 id 减去所有长度为 0 到 4 (2^28) 的 id 为 2^ 35 - 2^28 = 34 091 302 912,这仍然很大:)

于 2010-01-12T21:54:23.660 回答
6

您不能“唯一缩短”任意字符串。鸽巢原理等等。

您想要做的(以及 AFAIK 的 url-shortening 服务所做的)是保留一个包含所有提交内容的数据库,以及使用的短字符串。然后你可以在数据库中查找它。

您可以通过简单地递增一个数字并每次对其进行 Base64 编码来生成短字符串。

于 2010-01-12T21:11:43.863 回答
0

您可以使用散列(例如 CRC32)来生成非常短的 URL。当您减少数据时,您将永远无法获得“唯一”的 URL,因此必须存在冲突。

于 2010-01-12T21:13:38.943 回答
0

存储一个随机的字母数字字符串并将其用于您的短网址。使其长度成为您认为最适合您的网站和用户的长度,例如www.yoursite.com/d8f3

于 2010-01-12T21:11:45.140 回答
-2

Hey nll, as several other people has told you.. If you start compressing the url into something small it will be impossible for you to keep it unique. That said, you need to make your own coding for every url submitted to you. One way (easy) to do it is, try to create a database from the submitted urls and then generate a guid field for each and then get a substring from it ensuring everytime you register something is totally different from the previous.

For instance: www.google.com with the guid F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4 -> http://www.mysite.com/?q=CEB2

As more characters as you use, more amount of links you can keep track on. for this sample you will have 65536 different links (with only 4 characters on hex).

Hope this helps.

于 2010-01-12T23:32:04.570 回答