如题,看到穷游的主键是这种形式的,请教下应如何生成形如“V2UJY1FlBzdTbVI9”这样的主键? https://place.qyer.com/poi/V2UJY1FlBzdTbVI9/
Ruby 标准库有 SecureRandom.alphanumeric
p SecureRandom.alphanumeric(16) => "5Ov39BS5Ve0n4CET"
p SecureRandom.alphanumeric(24) => "CabSW7ijP9Hg1CojBziVajP9"
Rails API 里面有个 Base58
https://api.rubyonrails.org/classes/SecureRandom.html#method-c-base58
p SecureRandom.base58 # => "4kUgL2pdQMSCQtjE"
p SecureRandom.base58(24) # => "77TMHrHJFvFDwodq8w7Ev2m7"
如果你不希望有大写字母,可以用 Base36
https://api.rubyonrails.org/classes/SecureRandom.html#method-c-base36
p SecureRandom.base36 # => "4kugl2pdqmscqtje"
p SecureRandom.base36(24) # => "77tmhrhjfvfdwodq8w7ev2m7"
以上有重复概率,在插入的时候处理唯一错误,重试
require 'securerandom'
SecureRandom.hex #=> "eb693ec8252cd630102fd0d0fb7c3485"
https://ruby-doc.org/stdlib-2.2.10/libdoc/securerandom/rdoc/SecureRandom.html#method-c-hex
你不嫌弃的话可以看下我做的 url 短链接服务利用数据库主键 id 生成唯一短链接的 ruby 代码 https://github.com/printfinn/url_shortener/blob/master/app/models/link.rb。 这个可以保证不重复,而且(按我的理解)是 O(1) 的时间复杂度。 不知道你说的不可逆是指啥?逆回主键 id 吗?不可逆不知道,但可以做到防止遍历。比如可以考虑给这个 f(id) 前面加两位 prefix:
prefix = f(h(id) % (62 ** 2))
uid = "#{prefix}#{f(id)}"
f(x) 是数据库主键 id 转 a-zA-Z0-9 的函数
h(x) 可以是你设计的 hash function,别人猜不到你的 hash,也就无法遍历了
补充:如果你想不可逆,其实也容易,就是在设计 f(x) 时候不要按 a-zA-Z0-9 的顺序对应,而是自己设计一个表来查表,比如原来 0 对应 a,25 对应 z,26 对应 A,61 对应 9,你更改一下自己的映射表,比如 0 对应 f, 25 对应 8,总之不要被人猜出你的表就可以了。