在红宝石/ ActiveRecord的产生Instagram-或类似YouTube的不可猜测的字符串ID [英] Generating an Instagram- or Youtube-like unguessable string ID in ruby/ActiveRecord

查看:484
本文介绍了在红宝石/ ActiveRecord的产生Instagram-或类似YouTube的不可猜测的字符串ID的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在创建一个给定的ActiveRecord模型对象的实例,我需要生成一个稍短(6-8个字符)唯一的字符串作为URL的一个标识符来使用,在Instagram的的照片的URL风格(如的http://instagram.com/p/P541i4ErdL/ ,我只是炒是一个404)或YouTube的视频网址(如<一个href="http://www.youtube.com/watch?v=oHg5SJYRHA0">http://www.youtube.com/watch?v=oHg5SJYRHA0).

Upon creating an instance of a given ActiveRecord model object, I need to generate a shortish (6-8 characters) unique string to use as an identifier in URLs, in the style of Instagram's photo URLs (like http://instagram.com/p/P541i4ErdL/, which I just scrambled to be a 404) or Youtube's video URLs (like http://www.youtube.com/watch?v=oHg5SJYRHA0).

什么是去这样做的最好方法是什么?它是最简单的只是创建一个随机字符串反复直到它的独特之处?有没有一种方法散列/洗牌的整数ID以这样一种方式,用户无法改变一个字符(像我一样的404'd的Instagram上面的链接)黑客网址,并最终在一个新的记录?

What's the best way to go about doing this? Is it easiest to just create a random string repeatedly until it's unique? Is there a way to hash/shuffle the integer id in such a way that users can't hack the URL by changing one character (like I did with the 404'd Instagram link above) and end up at a new record?

推荐答案

您可以做这样的事情:

random_attribute.rb

module RandomAttribute

  def generate_unique_random_base64(attribute, n)
    until random_is_unique?(attribute)
      self.send(:"#{attribute}=", random_base64(n))
    end
  end

  def generate_unique_random_hex(attribute, n)
    until random_is_unique?(attribute)
      self.send(:"#{attribute}=", SecureRandom.hex(n/2))
    end
  end

  private

  def random_is_unique?(attribute)
    val = self.send(:"#{attribute}")
    val && !self.class.send(:"find_by_#{attribute}", val)
  end

  def random_base64(n)
    val = base64_url
    val += base64_url while val.length < n
    val.slice(0..(n-1))
  end

  def base64_url
    SecureRandom.base64(60).downcase.gsub(/\W/, '')
  end
end
Raw

user.rb

class Post < ActiveRecord::Base

  include RandomAttribute
  before_validation :generate_key, on: :create

  private

  def generate_key
    generate_unique_random_hex(:key, 32)
  end
end

这篇关于在红宝石/ ActiveRecord的产生Instagram-或类似YouTube的不可猜测的字符串ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆