在 ruby​​/ActiveRecord 中生成类似 Instagram 或 Youtube 的不可猜测的字符串 ID [英] Generating an Instagram- or Youtube-like unguessable string ID in ruby/ActiveRecord

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

问题描述

在创建给定 ActiveRecord 模型对象的实例后,我需要生成一个较短(6-8 个字符)的唯一字符串,用作 URL 中的标识符,采用 Instagram 照片 URL 的样式(例如 http://instagram.com/p/P541i4ErdL/,我只是把它混为 404)或 Youtube 的视频 URL(例如 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,使用户无法通过更改一个字符来破解 URL(就像我在上面的 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

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

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