phpmysqlhashtokenunique

How to make sure my hashes are unique?


I am creating short 5 character hashes to make unique classrooms for my students... a typical hash will look like AJ678.

I am generating the hash like this:

public function generateToken($length = 5)
{
    return strtoupper(substr(md5(rand()), 0, $length));
}

I am expecting many thousands of classrooms to be generated over the lifetime of the app... so eventually there will be a clash... I want to know how to make sure that every hash will be unique.

I have make the token field a unique field.

I would think that the best way to do this would be to generate the hash, then check if the hash already exists in my database, if it does then generate a new hash, else use the hash.

Is that the correct way to go about this?

EDIT: I am a bit insecure about implementing a function that calls itself... does this look right?

public function generateToken($length = 5)
{
    $token = strtoupper(substr(md5(rand()), 0, $length));
    if ($this->tokenExistsAlready($token)) {
        $this->generateToken();
    } else {
        return $token;
    }
}

public function tokenExistsAlready()
{
    $this->db->where('token', $token);
    $query = $this->db->get('classes');
    if ($query->num_rows() > 0) {
        return true;
    } else {
        return false;
    }
}

Solution

  • First, define "unique". Unique in our terms is a string of any length, that does not yet exist in your database.

    This pretty much answers your question. You can never be sure, that your string is unique, unless you check it against your database. The longer the string, the slimmer the chance. So in your case, I would have created a while loop checking the database. Starting with the second string you save in the database, you might (and probably will later down the timeline) hit two randomly generated strings in a row. So checking the uniqueness in a loop until you find the "unique" one is a good idea. Something abstract like this:

    $token = generateToken();
    
    while(tokenExists($token))
    {
        $token = generateToken();
    }
    

    Keep in mind, that nothing guarantees true uniqueness of a string. You may use the MySQL UUID() or UUID_SHORT(), PHP uniqid() or anything else, that generates a random string. But it still does not guarantee the said uniqueness unless you check it against the existing database.