Ruby on Rails - 生成 bit.ly 样式标识符

发布于 2024-09-10 04:29:44 字数 571 浏览 5 评论 0原文

我正在尝试生成与 bit.ly 网址相同样式的 UUID,例如:

http://bit [dot] ly/aUekJP

或 cloudapp 网址:

http://cl [dot] ly/1hVU

甚至更小,

我该怎么做? 我现在正在为 ruby​​ 使用 UUID gem,但我不确定是否可以限制长度并得到类似的东西。 我目前正在使用这个:

UUID.generate.split("-")[0] => b9386070

但我想要更小的并且知道它将是独一无二的。

任何帮助将非常感激:)


编辑注释:用 [dot] 替换点字母以解决 禁止的短链接

I'm trying to generate UUIDs with the same style as bit.ly urls like:

http://bit [dot] ly/aUekJP

or cloudapp ones:

http://cl [dot] ly/1hVU

which are even smaller

how can I do it?
I'm now using UUID gem for ruby but I'm not sure if it's possible to limitate the length and get something like this.
I am currently using this:

UUID.generate.split("-")[0] => b9386070

But I would like to have even smaller and knowing that it will be unique.

Any help would be pretty much appreciated :)


edit note: replaced dot letters with [dot] for workaround of banned short link

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

星光不落少年眉 2024-09-17 04:29:44

您在这里混淆了两种不同的事物。 UUID 是通用唯一标识符。即使世界各地同时创建了数百万个,它也很有可能是独一无二的。它通常显示为 36 位数字的字符串。您不能砍掉前 8 个字符并期望它是唯一的。

Bitly、tinyurl 等人存储链接并生成一个短代码来表示该链接。他们不会根据在数据存储中查找的代码重建 URL 并返回相应的 URL。这些不是 UUID。

在不了解您的应用程序的情况下,很难建议您应该使用哪种方法,但是您可以使用数字键将您指向的任何内容存储在数据存储中,然后使用 10 个数字和 22 个小写字母将密钥重新设置为 base32,也许可以避免明显的拼写错误问题,例如“o”“i”“l”等

编辑

在进一步调查中,有一个Ruby base32 gem 可用于实现 Douglas Crockford 的 Base 32 实现

5 个字符的 Base32 字符串可以表示超过 3300 万个整数和超过 10 亿个 6 位字符串。

You are confusing two different things here. A UUID is a universally unique identifier. It has a very high probability of being unique even if millions of them were being created all over the world at the same time. It is generally displayed as a 36 digit string. You can not chop off the first 8 characters and expect it to be unique.

Bitly, tinyurl et-al store links and generate a short code to represent that link. They do not reconstruct the URL from the code they look it up in a data-store and return the corresponding URL. These are not UUIDS.

Without knowing your application it is hard to advise on what method you should use, however you could store whatever you are pointing at in a data-store with a numeric key and then rebase the key to base32 using the 10 digits and 22 lowercase letters, perhaps avoiding the obvious typo problems like 'o' 'i' 'l' etc

EDIT

On further investigation there is a Ruby base32 gem available that implements Douglas Crockford's Base 32 implementation

A 5 character Base32 string can represent over 33 million integers and a 6 digit string over a billion.

终遇你 2024-09-17 04:29:44

如果您正在处理数字,您可以使用内置的 ruby​​ 方法

6175601989.to_s(30)
 => "8e45ttj" 

返回

"8e45ttj".to_i(30)
=>6175601989

,因此您不必存储任何内容,您始终可以解码传入的短代码。

这对于概念证明来说没问题,但你无法避免不明确的字符,例如:1lji0o。如果您只是想使用代码来混淆数据库记录 ID,那么这会很好用。一般来说,短代码应该易于记住并从一种媒体转移到另一种媒体,例如在某人的演示幻灯片上阅读它,或通过电话听到它。如果您需要避免使用难以阅读或难以“听到”的字符,您可能需要切换到生成可接受的代码并将其存储的过程。

If you are working with numbers, you can use the built in ruby methods

6175601989.to_s(30)
 => "8e45ttj" 

to go back

"8e45ttj".to_i(30)
=>6175601989

So you don't have to store anything, you can always decode an incoming short_code.

This works ok for proof of concept, but you aren't able to avoid ambiguous characters like: 1lji0o. If you are just looking to use the code to obfuscate database record IDs, this will work fine. In general, short codes are supposed to be easy to remember and transfer from one medium to another, like reading it on someone's presentation slide, or hearing it over the phone. If you need to avoid characters that are hard to read or hard to 'hear', you might need to switch to a process where you generate an acceptable code, and store it.

不打扰别人 2024-09-17 04:29:44

我发现它简短而可靠:

def create_uuid(prefix=nil)
  time   = (Time.now.to_f * 10_000_000).to_i
  jitter = rand(10_000_000) 
  key    = "#{jitter}#{time}".to_i.to_s(36)
  [prefix, key].compact.join('_')
end

它会输出如下所示的独特密钥:'3qaishe3gpp07w2m'
减少“抖动”大小以减少密钥大小。

警告:
这不能保证唯一(使用 SecureRandom.uuid),但它非常可靠:

10_000_000.times.map {create_uuid}.uniq.length == 10_000_000

I found this to be short and reliable:

def create_uuid(prefix=nil)
  time   = (Time.now.to_f * 10_000_000).to_i
  jitter = rand(10_000_000) 
  key    = "#{jitter}#{time}".to_i.to_s(36)
  [prefix, key].compact.join('_')
end

This spits out unique keys that look like this: '3qaishe3gpp07w2m'
Reduce the 'jitter' size to reduce the key size.

Caveat:
This is not guaranteed unique (use SecureRandom.uuid for that), but it is highly reliable:

10_000_000.times.map {create_uuid}.uniq.length == 10_000_000
何以笙箫默 2024-09-17 04:29:44

保证唯一性的唯一方法是保留全局计数并在每次使用时递增:00000001 等。

The only way to guarantee uniqueness is to keep a global count and increment it for each use: 0000, 0001, etc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文