【问题标题】:Generate a unique tinyurl-like ID but randomly (not mysql row id to base64)生成一个唯一的类似 tinyurl 的 ID,但随机生成(不是 mysql 行 ID 到 base64)
【发布时间】:2013-09-30 07:12:03
【问题描述】:

我需要生成唯一的 URL,例如 tinyurl:domain.com/pgDzs7、domain.com/ab4dh3 但是(!)问题是我不希望用户有可能通过更改 URL 中的最后一个字母来查看上一个和下一个 URL。

例如,如果有人创建了一个获取 URL domain.com/pgDzs7 的内容,我希望下一个访问者获得一个完全不同的唯一 URL(例如,“ab4dh3”),这样没有人会发现这些 URL 是如何产生的生成并查看其他用户的内容,除非他们知道其 URL。

我在 Stackoverflow 上找到的只是将表的主整数键转换为 base64 形式。但我需要不同的解决方案,它也不会产生冲突,也没有 for/while 循环(如果可能的话),因为我的 MySQL 表有几十个 GBytes。

【问题讨论】:

  • 我认为没有办法保证不会产生冲突。只要很少发生冲突,您的while 循环应该只迭代 1 或 2 次,这应该不会太糟糕。只要你的数据库中的值有索引,检查代码是否已经被使用应该很快。

标签: php sql url hash tinyurl


【解决方案1】:

您可以制定一个公式来获取下一个索引。 喜欢:LastID*2+5

您不会有 colisions 或循环来检查该 id 之前是否使用过。

【讨论】:

  • 20000000 = 40000000 + 5 = 40000005 和 20000001 = 40000002 + 5 = 40000007 -- 似乎没有让 ID 看起来不同。
  • 那么,20 和 21 呢?现在是 45 和 47。
  • 你不理解算法。这是一个例子:clic me
  • 我明白了。让我们假设这张桌子是空的。第一个元素的 ID 是 1。那么我们应用公式后的结果 ID 是 7。第二个元素的 ID 是 2。那么结果是 9。结果之间的差总是 +2。我知道我可以使用任何公式,但这是主要问题——什么样的公式?
  • 你还是误解了我说的话...好吧,表格是空的,第一个 id 是 1。应用公式的结果 ID 是 7,你保存那个数字所以第二个 ID 是 7,应用公式再次下一个数字是 19
【解决方案2】:

您可以使用模幂将您的键映射到不同的键,您可以轻松地映射回原来的键,利用模幂的一些特殊属性,其中模数的形式为 p*qp 和 @987654323 @素数。

具体例子:

p=31
q=17
a=343
b=7

such that (a*b) = 1 mod (p-1)*(q-1)

given original secret index "id", you have public index "pid"

pid = id ^ a mod p*q

and given the public id "pid" you can find the secret id

id = pid ^ b mod p*q

这会生成下表:

id      pid     recovered_id
0       0       0
1       1       1
2       349     2
3       334     3
4       64      4
5       129     5
6       99      6
7       267     7
8       202     8
9       359     9
10      226     10
11      207     11
12      296     12
13      259     13
etc

最大 id 为 p*q-1 (526),之后循环重复。

当然,您将需要更大的pq,以及id 的偏移量,但原则肯定会奏效。

【讨论】:

  • 如果我在表中有 4000 万条记录,并计划拥有多达 150-2 亿条记录,那么如何定义 p/q/a/b 变量?我有点困惑。
  • @Gregory 这基本上是公钥密码学中发生的事情,因此您可以使用它的算法和工具。对于您的目的而言,这可能有点过多,但它绝对是一种相当安全的方法,无需预先计算/渲染数百万个唯一值即可获得不可预测的 1:1 映射。
【解决方案3】:

我找到了更好的解决方案。我所需要的只是打乱字母表 [a-zA-Z0-9],这样访问者就无法迭代 URL。至少不会像以前那么容易了。

【讨论】:

  • 当然,这不是最好的解决方案。但是,如果您需要防止 URL 重复,它比传统的 base64 转换要好得多。
猜你喜欢
  • 2011-06-14
  • 2014-05-26
  • 1970-01-01
  • 2011-06-20
  • 2010-09-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多