PHP简短的唯一ID生成使用auto_increment吗? [英] PHP short unique ID generation using auto_increment?

查看:107
本文介绍了PHP简短的唯一ID生成使用auto_increment吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想生成一个简短的唯一ID,而不必检查冲突.

I would like to generate a short, unique ID without having to check for collisions.

我目前正在执行类似的操作,但是我当前生成的ID是随机的,并且在循环中检查冲突很烦人,如果记录数量显着增长,它将变得很昂贵.

I currently do something like this, but the ID I currently generate is random and checking for collisions in a loop is annoying and will get expensive if the number of records grows significantly.

通常不用担心冲突,但是我要生成的唯一ID是一个简短的唯一字符串,由5-8个字母数字组成,就像tinyurl一样.

Normally worrying about collisions isn't an issue, but the unique ID I want to generate is a short unique string 5-8 characters, alpha-numeric, like tinyurl does.

我想以5个字符开头,如果我输入了6000万个条目,则转到6 ..依此类推.

I would like to start out with 5 characters and if I hit 60 million entries, then go to 6.. so on and so forth.

为此,我想我可以使用对用户隐藏的auto_increment值,并用MD5或其他方法向他们显示,以从中生成唯一的字符串.

To this end, I was thinking I could use an auto_increment value that is hidden from the users, and present them instead with an MD5 or some other method to generate a unique string from that.

生成的字符串不应看起来是线性的,因此将auto_incremented ID转换为base 36 [0-9A-Z]有点太简单了,但是类似的功能正是我要解决的问题.

Generated strings should not appear to be linear, so simply converting the auto_incremented ID into base 36 [0-9A-Z] is a bit too simplistic, but a function something like that is where I'm going with this.

安全性不是问题,因为它将不会用于保护信息.它只是较长字符串的快捷方式. 谢谢.

Security is not an issue as this will not be used to secure information. It is simply a shortcut to a longer string. Thank you.

谢谢您的建议,对您的延迟深表歉意.牙医..

Thank you for your suggestions and sorry for the delay. Dentist..

推荐答案

您将需要一些在构造上正确的东西,即置换函数:这是一个对一个整数进行一对一,可逆映射的函数(您的顺序计数器). 一些示例(这些方法的任何组合也都可以使用):

You'll need something that's correct by construction, i.e. a permutation function: this is a function that does a one-to-one, reversible mapping of one integer (your sequential counter) to another. Some examples (any combination of these should also work):

  • 反转一些位(f.i.使用XOR,PHP中为^)
  • 交换位(($ i& 0xc)>> 2 |($ i& 0x3)<<< 2),或只是反转所有位的顺序
  • 以最大范围为模添加一个常数(如果将其与上述范围相结合,则必须为两个因数)

示例:此函数会将0、1、2、3、5 ...转换为13、4、12、7、15 ..,最大数字为15:

Example: this function will convert 0, 1, 2, 3, 5, .. into 13, 4, 12, 7, 15, .. for numbers up to 15:

$i=($input+97) & 0xf;
$result=((($i&0x1) << 3) + (($i&0xe) >> 1)) ^ 0x5;

编辑

一种更简单的方法是使用线性同余生成器(LCG,通常用于生成随机数),该生成器由以下形式的公式定义:

An easier way would to use a linear congruential generator (LCG, which is usually used for generating random numbers), which is defined by a formula of the form:

X_n+1 = (a * X_n + c) mod m

对于 a,c和m的好值,它们是X_0,X_1的序列. X_m-1将一次包含0到m-1之间的所有数字.现在,您可以从线性增加的索引开始,并将LCG序列中的 next 值用作秘密"密钥.

For good values of a, c and m, the sequence of X_0, X_1 .. X_m-1 will contain all numbers between 0 and m-1 exactly once. Now you can start from a linearly increasing index, and use the next value in the LCG sequence as your "secret" key.

EDIT2

实施: 您可以设计自己的LCG参数,但是如果弄错了,它将无法涵盖完整范围(因此有重复项),因此我将在本文:

Implementation: You can design your own LCG parameters, but if you get it wrong it won't cover the full range (and thus have duplicates) so I'll use a published and tried set of parameters here from this paper:

a = 16807, c = 0, m = 2147483647

这给你2 ** 31的范围.使用pack(),您可以将生成的整数作为字符串,base64_encode()使其成为可读的字符串(最多6个有效字符,每个字节6位),因此这可能是您的功能:

This gives you a range of 2**31. With pack() you can get the resulting integer as a string, base64_encode() makes it a readable string (of up to 6 significant characters, 6 bits per byte) so this could be your function:

substr(base64_encode(pack("l", (16807 * $index) % 2147483647)), 0, 6)

这篇关于PHP简短的唯一ID生成使用auto_increment吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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