Jump to content

Recommended Posts

I would like to add a second unique identifier for each record in a database table which is independent of the table's PK and offers the following:

  1. Very difficult to guess.
  2. Almost zero possibilities of duplicates.
  3. Appears similar to other unique identifiers (such as software keys, etc) seen by typical users.
  4. As easy as possible for someone to give the identifier to another person.

My objectives 1 and 2 appear to be met by using something like 54b7ac997faf29b772827ff10f6128eb generated by bin2hex(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)).  Agree, or something different?

 

Objective's 3 and 4 still need some work.

 

I would like to shorten it by using the full alphabet and zero to 9.

 

Should I limit alphabet characters to uppercase only?

 

Which characters should be excluded?  0 (zero) and O (letter o) seem confusing.  Should they both be excluded?  1 (one) and l (letter L) seem confusing, but maybe only if I don't limit to uppercase only.  Is U and V a problem? Any other characters?

 

How should I implement this?  I am thinking of something like the following using https://github.com/ademarre/binary-to-text-php.  Agree, or something different? Should I use base 5, or something different?

$encoder = new Base2n(5, '23456789ABCDEFGHJKMNPQRSTUVWXYZ');
$raw_token = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM);
$activation_code = $encoder->encode($raw_token);

What should be stored in the database?  The encoded or pre-encoded version?  Seems to me the encoded version should as it will make future queries easier, but would like other opinions.  If I store the encoded version, what will be the maximum size of the string?

 

How should it be formatted?  For instance, maybe each 4 characters separated by a hyphen?

 

Are there other important factors which I did not address above?

 

Thank you

Link to comment
https://forums.phpfreaks.com/topic/300030-strong-record-identifier/
Share on other sites

Allow me to be the first to ask, why? What are you doing? Sounds a lot like the XY problem

 

I have database records owned and maintained by different individuals.  I wish to allow one user the ability to synchronize to another user's data.  I don't wish to make the PK public, and thus am asking how to best come up with a second "public" identifier.

 

@NotionCommotion:  Use a UUID: http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_uuid

mysql> SELECT UUID();
           -> '6ccd780c-baba-1026-9564-0040f4311e29'

 

Thanks Psycho,

 

Per the documentation, using them might not be secure.  Probably okay for my needs, but worth considering.

 

More so, form a UX prospective, I wonder if doing so will bring more difficultly to the user.  I see that Microsoft using something like MWX42-DF8S1-4FR8G-FSDF3-FDSD1 as the software key.  It appears that confusing letters have been removed, and by using the full range of letters, it is slightly shorter.

 

If used, just store them as CHAR(36) with the hyphens?

 

Although UUID() values are intended to be unique, they are not necessarily unguessable or unpredictable. If unpredictability is required, UUID values should be generated some other way.

 

Edited by NotionCommotion

UUIDs are definitely no safe choice when you need unpredictability. While a particular implementation might happen to use strong random numbers, it's also possible to implement UUIDs with simple time-based numbers.

 

If you want human-friendly random numbers, consider using Crockford's Base32 encoding. It's optimized for readability (ambiguous symbols are already excluded) and relatively compact compared to hexadecimal encoding. A 128-bit random number fits into a 26-character Base32 string. You may append a check symbol for error detection, and of course can add hyphens to further increase readability.

 

By the way, I'd use the new PHP 7 CSPRNG extension instead of Mcrypt to generate random numbers. If you don't have PHP 7 yet, there are several compatibility libraries. There's nothing wrong with mcrypt_create_iv(), but the underlying Mcrypt library has been abandoned back in 2007, and the PHP core developers have already considered removing the extension.

Edited by Jacques1

Thanks Jacques1,

 

Any reason not always to use a 128-bit random number and encode it for readability?

 

Is there a class to implement Crockford's solution, or need I code it myself?  By the way, never knew why "U" was excluded before reading it.

 

No, still with PHP5.  Guess it is time to upgrade!

 

Thanks again

Any reason not always to use a 128-bit random number and encode it for readability?

 

Unpredictability isn't always a requirement, so non-secure random numbers like UUIDs do make sense in some cases.

 

 

 

Is there a class to implement Crockford's solution, or need I code it myself?

 

There are several libraries on GitHub like this one.

Unpredictability isn't always a requirement, so non-secure random numbers like UUIDs do make sense in some cases.

 

Where do they make sense?  Being unpredictable by itself can't be the reason.  They don't appear to be more readable than other solutions, and maybe less.  Agree?  I assume the primary reason is that they require less server resources.  Is this the only compelling reason?

Getting strong random numbers is actually hard, especially when you're dealing with different operating systems. So for general applications which need to work everywhere it makes a lot of sense to pick a simpler, time-based approach whenever possible. Why UUIDs? Because it's a standardized format which a lot of applications can handle out-of-the-box.

 

In your specific case, you do have access to a strong random number generator, so by all means, use it.

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.