Gem 短域名是如何实现的

camel · 2012年05月13日 · 最后由 heliang7 回复于 2012年05月17日 · 5441 次阅读

类似

http://bit.ly/rEex7g

这样的短域名要保证惟一是如何实现的,第一感觉是使用 UUID,可是那样太长了,有没有比较好用的算法或思路,谢谢。

Base62 就可以。

#1 楼 @pongyo base32 吧,这个看起来还行,谢谢 https://github.com/levinalex/base32

自增的 bigint 就行了,0-9, a-z ,A-Z 是 62........ 最多再加一个 k(hash 后的 url)-v( id ) 库确保 url 唯一

ruby -e "puts 123456.to_s(36)"
2n9c

Ruby 本身就可以 Base36 呢

#4 楼 @clearJiang #5 楼 @hooopo 不行啊,这样相当于直接暴露了 id,自增的 id 属于有意义的字段。 转码就是为了把 id 隐藏,否则就不用转了。

#6 楼 @camel shorturl 的本意并不是隐藏 id, 只是为了一些场景 (比如微薄的 140 字) 压缩 url 占用的空间。这个并不是 slug url, 没什么意义的

#7 楼 @clearJiang 我现在是要隐藏 id。 我的需求与 shorturl 有一点不太一样:我要隐藏的是 user_id,如果向外界暴露自增的 id,可能会被临近值攻击。如我暴露的 user_id=1000,别人就可以尝试 999,1001 攻击。

#6 楼 @camel 豆瓣现在还是自增 id,而且暴露在外面。 我有时候搞不懂为啥不可以暴露?是为了伪造用户数量的时候可以不被别人发现?

#9 楼 @hooopo 但愿是我多虑了,不过我想能隐藏会好一点。

#8 楼 @camel 这个问题不大,你自己设置一个 RANDOM_FLAG = 121212121, (id^RANDOM_FLAG).to_base62, 获取的时候 (id.from_base62) ^ RANDOM_FLAG

#10 楼 @camel 有的网站是为了这种考虑隐藏起来,也有很多网站没有隐藏 id 的,比如 so 和 zhihu。 我觉得这属于一个不太重要的细节,至于想防爬取,可以通过验证码等其他手段。不能因为这个增加开发的复杂度。

原来那种叫 Base36

#13 楼 @huacnlee #5 楼 @hooopo Ruby 的 to_s 支持 Base 2-36。 http://ruby-doc.org/core-1.9.3/Fixnum.html#method-i-to_s

才发现Base原来就是所谓的进制

after_create {
  begin
    # 4 bytes => 32 bits => 4,294,967,296 unique values
    self.profile_slug = ActiveSupport::SecureRandom.hex(4)
    self.save!
  rescue ActiveRecord::RecordNotUnique => e
    retry
  end
}

试试这个 ~。~

Hash 的速度会有些慢吧,而且数量大了以后碰撞的概率很高。

Github 的 git.io 是用這個實現的: https://github.com/technoweenie/guillotine

#15 楼 @raven 这个方法好。虽然 Hash 肯定会产生碰撞,但概率低到一定程度时,就可以认为是惟一的。

这个肯定是 guid

#18 楼 @camel Hash 碰撞?我想 rescue ActiveRecord::RecordNotUnique => e 解决了唯一性的问题。

#20 楼 @raven 纳尼,Sorry 只看了一半,的确可以解决惟一性问题。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号