我想生成一个唯一的4-6字符长的字母数字字符串保存在db与每个记录(用户)。db字段有一个唯一的索引,所以试图保存一个已经存在的字符串会产生一个错误。现在,我正在生成一个随机字符串并使用try-catch,因此,当添加一个新记录时,如果它抛出异常,我将生成另一个随机字符串并尝试再次保存,代码将继续尝试,直到成功添加一个记录。整个解决方案不仅看起来沉重而且丑陋,所以我想改变它。我对一个优雅的解决方案很感兴趣,所以欢迎任何帮助/指导。
与给定的信息:
- id必须唯一
- id不能是数字
- id不能表示连续系列
- id将不会被用户输入
PHP函数uniqid正是您需要的。虽然它返回一个13个字符长的十六进制值。
** Edit
是的,uniqid
将返回一个连续的数字,但是我们可以很容易地解决这个问题。考虑以下代码
class IDGenerator {
//const BIT_MASK = '01110011';
static public function generate() {
$id = uniqid();
$id = base_convert($id, 16, 2);
$id = str_pad($id, strlen($id) + (8 - (strlen($id) % 8)), '0', STR_PAD_LEFT);
$chunks = str_split($id, 8);
//$mask = (int) base_convert(IDGenerator::BIT_MASK, 2, 10);
$id = array();
foreach ($chunks as $key => $chunk) {
//$chunk = str_pad(base_convert(base_convert($chunk, 2, 10) ^ $mask, 10, 2), 8, '0', STR_PAD_LEFT);
if ($key & 1) { // odd
array_unshift($id, $chunk);
} else { // even
array_push($id, $chunk);
}
}
return base_convert(implode($id), 2, 36);
}
}
echo IDGenerator::generate();
会得到像
这样的结果ivpa493xrx7
d173barerui
evpoiyjdryd
99ej19mnau2
因为没有添加或修改任何东西,除了打乱周围的位,不应该有任何重复的值,一切看起来都是随机的。瞧!
**更新(2014-02-24)**
我更新了这段代码,因为它最初发布的时间。