ruby-on-rails-3 - ROR - 为 DB ID 生成字母数字字符串

标签 ruby-on-rails-3 encoding hash unique

在我们的 DB 中,每个 Person 都有一个 ID,它是 DB 生成的、自动递增的整数。现在,我们想要生成一个更加用户友好的字母数字 ID,它可以公开显示。类似护照号码的东西。我们显然不想向用户公开数据库 ID。出于这个问题的目的,我将我们需要生成的内容称为 UID

注意 :UID 并不意味着要替换 DB ID。您可以将 UID 视为 DB ID 的更漂亮版本,我们可以将其提供给用户。

  • 我想知道这个 UID 是否可以是 DB ID 的函数。也就是说,我们应该能够为给定的 DB ID 重新生成相同的 UID。
  • 显然,除了数据库 ID 之外,该函数还将采用“盐”或键。
  • UID 不应是连续的。也就是说,两个相邻的 DB ID 应该生成视觉上不同的 UID。
  • 不严格要求 UID 是不可逆的。也就是说,如果有人研究了几天 UID 并且能够逆向工程并找到 DB ID,那也没关系。我认为这不会对我们造成任何伤害。
  • UID 应仅包含 A-Z(仅大写)和 0-9。没有其他的。并且不应包含可能与其他字母或数字混淆的字符,例如 0 和 O、l 和 1 等。我猜 Crockford 的 Base32 编码可以解决这个问题。
  • 无论 DB ID 的大小如何,UID 都应该是固定长度(10 个字符)。我们可以用一些常量字符串填充 UID,使其达到所需的固定长度。 DB ID 可以增长到任何大小。因此,该算法不应有任何此类输入限制。

  • 我认为解决这个问题的方法是:

    第 1 步:散列。

    我已经阅读了以下哈希函数:
  • SHA-1
  • MD5
  • Jenkin's

  • 散列返回一个长字符串。我在 here 上读到了一种叫做 XOR 折叠的东西,可以将字符串缩短到更短的长度。但我找不到太多相关信息。

    第 2 步:编码。

    我阅读了以下编码方法:
  • Crockford Base 32 编码
  • Z-Base32
  • Base36

  • 我猜编码的输出将是我正在寻找的 UID 字符串。

    第 3 步:解决冲突。
  • 为了解决冲突,我想知道是否可以在生成 UID 时生成一个随 secret 钥并在函数中使用这个随 secret 钥。
  • 我可以将这个随机键存储在一列中,以便我们知道使用什么键来生成该特定 UID。
  • 在将新生成的 UID 插入表中之前,我会检查唯一性,如果检查失败,我可以生成一个新的随 secret 钥并使用它来生成一个新的 UID。可以重复此步骤,直到找到特定 DB ID 的唯一 UID。

  • 我很想得到一些专家的建议,以了解我是否沿着正确的路线前进,以及我如何实际实现这一点。

    我将在 Ruby On Rails 应用程序中实现它。因此,请在您的建议中考虑到这一点。

    谢谢。

    更新

    评论和回答让我重新思考和质疑我的要求之一:我们需要能够在分配一次后为用户重新生成 UID。我想我只是想确保安全,在我们丢失用户 UID 的情况下,如果它是用户现有属性的函数,我们将能够取回它。但我想我们可以通过使用备份来解决这个问题。

    因此,如果我取消该要求,则 UID 基本上会变成一个完全随机的 10 个字符的字母数字字符串。我正在添加一个包含我提议的实现计划的答案。如果其他人提出了更好的计划,我会将其标记为答案。

    最佳答案

    正如我在问题更新中提到的,我认为我们要做的是:

  • 预先生成足够多的随机且唯一的十个字符的字母数字字符串。没有散​​列或编码。
  • 以随机顺序将它们存储在表中。
  • 创建用户时,选择第一个这些字符串并将其分配给用户。
  • 在将它分配给用户后,从 ID 池中删除它。
  • 当池减少到一个较低的数字时,用新的字符串补充池,显然要进行唯一性检查。这可以在由观察者发起的延迟作业中完成。
  • 预生成的原因是我们将所有昂贵的唯一性检查卸载到一次性预生成操作。
  • 当从这个池中为新用户挑选一个 ID 时,唯一性是有保证的。因此,创建用户的操作(非常频繁)变得很快。
  • 关于ruby-on-rails-3 - ROR - 为 DB ID 生成字母数字字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9600816/

    相关文章:

    Html.tohtml() 之后的 Android Spannable 文本编码

    php - 这个散列有多安全? (PHP)

    json - 无法将字符串映射转换为 json

    ruby-on-rails - 如何在 Rails 3.1 中获取资源的绝对 URL?

    encoding - 如何编码/解码空字符串

    ruby-on-rails - Rails 3.1 pre 迁移问题

    c - 在 ICU 中打印 UTF-8 字符串

    java - 使用不同编码编码的两个不同字符串是否可以具有相同的字节序列?

    ruby-on-rails - 带有可选参数的 Rails url_for 命名路由

    ruby - 投票时间 - 从 "next noon"开始,持续 24 小时 - ruby​​ on rails