在Javascript中生成唯一ID

时间:2012-08-15 01:50:55

标签: javascript database algorithm

我想实现类似于Imgur的保存系统,如果用户按下按钮,则返回唯一的5个字符值。以下是我到目前为止的情况:

数据库后端使用从5308416开始的自动递增ID。我使用修改的Radix函数(见下文)将这些数字ID转换为字符。我使用反向函数来查找字符ID,返回数字数据库ID。

function genID (value)
{
    var alphabet = "23456789BCDFGHJKLMNPRSTVWXYZbcdfghjkmnpqrstvwxyz";

    var result = "";
    var length = alphabet.length;

    while (value > 0)
    {
        result = alphabet[value % length] + result;
        value  = Math.floor (value / length);
    }

    return result;
}

问题是这些生成的ID是非常可预测的。我的问题是,如何使生成的ID看起来随机但仍然是唯一的(所以我可以在数据库中查找它们作为数字)。我在考虑使用一些加密算法,但不知道从哪里开始。任何帮助或建议将不胜感激(也许还有一种更好的方法)。

2 个答案:

答案 0 :(得分:1)

你必须能够双向进行(即将整数转换为哈希值并再次返回)吗?如果您可以存储哈希并以这种方式查找内容,那么创建一个产生难以猜测但完整的哈希空间的函数相对容易。您使用素数生成一个序列,只有在所有可能的排列都用完后才会重复。

以下PHP示例是from my own code,改编自this site

function hash($len = 6) {
    $base = 36;
    $gp = array(1,23,809,28837,1038073,37370257 /*,1345328833*/);
    $maxlen = count($gp);
    $len = $len > ($maxlen-1) ? ($maxlen-1) : $len;
    while($len < $maxlen && pow($base,$len) < $this->ID) $len++; 
    if($len >= $maxlen) throw new Exception($this->ID." out of range (max ".pow($base,$maxlen-1).")");
    $ceil = pow($base,$len);
    $prime = $gp[$len];
    $dechash = ($this->ID * $prime) % $ceil;
    $hash = base_convert($dechash, 10, $base);
    return str_pad($hash, $len, "0", STR_PAD_LEFT);
}

在JavaScript中实现它很容易,但理想情况下你也不需要 - 你的表上有一个插入触发器,用该算法的结果填充一个哈希字段(适用于SQL,疗程)。

答案 1 :(得分:0)

通过将服务器端自动递增数与当前日期/时间块或随机数组合,可以生成不可预测但唯一的ID。服务器端自动递增数字保证唯一性,日期/时间块或随机数消除了可预测性。

对于字符串形式的唯一ID,它将服务器端唯一编号作为输入,并在客户端上添加日期/时间块,您可以这样做:

function genID(serverNum) {
    return(serverNum + "" + (new Date).getTime());
}

或使用随机数:

function genID(serverNum) {
    return(serverNum + "" + Math.floor(Math.random() * 100000));
}

但是,最好在服务器上添加日期/时间元素,并将整个唯一ID存储在数据库中。