NotionCommotion Posted December 27, 2015 Share Posted December 27, 2015 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: Very difficult to guess. Almost zero possibilities of duplicates. Appears similar to other unique identifiers (such as software keys, etc) seen by typical users. 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 Quote Link to comment Share on other sites More sharing options...
benanamen Posted December 27, 2015 Share Posted December 27, 2015 (edited) Allow me to be the first to ask, why? What are you doing? Sounds a lot like the XY problem Edited December 27, 2015 by benanamen Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted December 27, 2015 Author Share Posted December 27, 2015 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. Quote Link to comment Share on other sites More sharing options...
Barand Posted December 27, 2015 Share Posted December 27, 2015 Sounds a lot like the XY problem What is this "XY problem" to which you keep alluding? 1 Quote Link to comment Share on other sites More sharing options...
Psycho Posted December 27, 2015 Share Posted December 27, 2015 @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' Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted December 27, 2015 Author Share Posted December 27, 2015 (edited) @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 December 27, 2015 by NotionCommotion Quote Link to comment Share on other sites More sharing options...
benanamen Posted December 27, 2015 Share Posted December 27, 2015 What is this "XY problem" to which you keep alluding? Surprised you dont know, and yet you are fully aware of it. *PS: What happened to your google? http://xyproblem.info/ Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted December 27, 2015 Author Share Posted December 27, 2015 Please keep replies on topic. I am aware of the XY debate and sure Barand is as well, but would appreciate if you please assume I really want only Y. Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted December 27, 2015 Share Posted December 27, 2015 (edited) 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 December 27, 2015 by Jacques1 Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted December 27, 2015 Author Share Posted December 27, 2015 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 Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted December 27, 2015 Share Posted December 27, 2015 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. Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted December 28, 2015 Author Share Posted December 28, 2015 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? Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted December 28, 2015 Share Posted December 28, 2015 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. Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted December 28, 2015 Author Share Posted December 28, 2015 In your specific case, you do have access to a strong random number generator, so by all means, use it. Works for me. Thanks Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.