代码之家  ›  专栏  ›  技术社区  ›  Lasse Espeholt

如何为联机资源生成唯一的文本ID

  •  0
  • Lasse Espeholt  · 技术社区  · 15 年前

    我想生成一个唯一的ID,它将在URL中用于标识特定的资源。原则上与pastebin.com等网站相同。

    ID和资源不是很秘密,但我希望它是这样,这样您就不能减少一个ID,然后再获得另一个用户资源。我在想 CHAR(8) 它在一个URL中看起来很好,并且仍然足够大以减少猜测的机会。但是我如何生成这个呢?对于int,可以使用 auto_increment primary key 以确保独特性。

    但是如果我按顺序做

    1. 生成一个 字符(8) 在我的申请中
    2. 确保此ID不存在。
    3. 如果不存在,则存储,否则转到1。

    我得包2个。3。在原子事务中。

    但是有更好的方法吗?或者我不应该关心支票(2),因为不经常发生冲突。如果这有帮助的话,我使用MySQL和.NET(C)。是否可以以某种方式“加密”一个自动递增的int作为文本ID,并以精确的8(或10)个字符再次对其进行解密。

    我读过 Need a smaller alternative to GUID for DB ID but still unique and random for URL 这很有用,但MySQL不支持使用guid(据我所知)。但对质量的评论 LongToShortCode 也希望采用螺纹中的方法。

    注意:不能更改资源,只能查看。

    最好的问候, 拉塞

    4 回复  |  直到 15 年前
        1
  •  1
  •   AllenG    15 年前

    MySQL实现了UUID。它似乎是一个具有不同名称的GUID。所以这个选项仍然对您可用。

    如果你还在使用 char(8) ,那么您就需要担心ID的唯一性,因为如果您查看的是服务的URL,那么在人们开始报告问题之前,您可能不会知道发生了冲突。

        2
  •  1
  •   Paul Creasey    15 年前

    您可以使用一个int标识,然后在使用它之前对其进行加密/解密,但在重载情况下这可能不是最好的主意。

        3
  •  0
  •   zebediah49    15 年前

    做这种伪原子的简单方法是

    1. 生成随机字符串
    2. 存储字符串(实际上是保留字符串)
    3. 检查是否存在另一个
    4. 如果存在另一个,请删除刚才创建的,然后返回到步骤1。

    冲突仍然可能发生,但当它们发生时,会导致两个线程重试,在本例中这不是问题。

    编辑:我建议为您的生成函数取密码散列的前几个字符,但这并不重要。

        4
  •  0
  •   Lasse Espeholt    15 年前

    我想我会这样做的: 8个字符的文本ID可以存储最多64^8=2^48的数字。

    然后我将使用两列:

    • ID,int 2^32自动递增
    • 兰德,int 2 ^ 16

    然后,当我添加一行时,我将生成一个随机的2^16整数,并将其放入新行中。然后,只需从两个数字组合中生成文本ID。检索很简单,只需将其拆分,然后在数据库中进行简单的查找。荒谬的简单解决方案,应该消除行冲突,并且足够随机(2^16),以减少猜测。

    对此方法的反馈将不胜感激。

    推荐文章