====== PHP RFC: Improve uniqid() uniqueness ====== * Version: 0.9 * Date Created: 2016-09-12 * Date Modified: 2016-09-12 * Author: Yasuo Ohgaki * Status: Inactive * First Published at: http://wiki.php.net/rfc/uniqid ===== Introduction ===== uniqid() is supposed to create unique ID based on time. Current implementation does not make sure uniqueness of result because it relies on system time. ==== Why it is not unique ==== Current implementation uses usleep(1) to generate unique ID based on microtime(). Most systems adjust system time by NTP or similar. System time is adjusted by magnitude of milliseconds or even seconds constantly. Therefore, usleep(1) does not guarantee uniqueness of return value on the same process/thread nor other process/thread. ==== Poor entropy source ==== Current implementation uses php_combined_lcd() and 9 digits float value as "more entropy". php_combined_lcg() is weak source of entropy. Since we have php_random_bytes() as better entropy source, it is preferred to use stronger entropy source. * Current entropy range: About 1 billion * Proposed entropy range: 2^50 or more. About 1048567 billions. ===== Proposal ===== * Change "more_entropy" option to int parameter to specify number of entropy chars. * Enable "more entropy" option by default. * Use php_random_bytes() as entropy source. string uniqid([string $prefix [, int $number_of_entropy_chars ]]); Where $number_of_entropy_chars are: * 0 for disable more entropy. (Compatible with current $more_entropy=FALSE) * 1 for 10 digits entropy. (Compatible with current $more_entropy=TRUE. About 30 bits entropy) * 13 to 255 for number of entropy [0-v]{13,255} chars. (13 chars = 65 bits entropy) == Note on usage == Users should never use uniqid() for any crypt related purposes even with this change. uniqid() does not provide crypt secure random value. Users should use random_bytes() for crypt purposes. == Note on performance == usleep(1) is not used when "more entropy" is used. Therefore, default behavior is about 25x faster. == Note on uniqueness == Although it is unlikely, uniqueness is _not_ guaranteed even with this proposal, but this proposal improves uniqueness a lot. This nature will be documented in the manual. ===== Discussions ===== == User shouldn't use uniqid(). uniqid() should be deprecated == It provides good enough unique ID and many users use uniqid() for test scripts. We don't have to deprecate it. == This gives false sense of security == It mitigates risks of misuses, but users should not misunderstand new uniqid() generates crypt secure random values. ===== Backward Incompatible Changes ===== Almost all uniqid() usages do not care about return value chars nor length. Therefore, BC will be minimum. * https://searchcode.com/?q=uniqid&loc=0&loc2=10000&lan=24 Windows CYGWIN environment requires "more entropy" always and default "more entropy" optione for CYGWIN is TRUE by default. It raises E_WARNING when "more entropy" option is FALSE. ==== Default return value length ==== * Return value is longer than current default. (13 -> 23 chars) Current implementation output example: $ php -r 'var_dump(uniqid(), uniqid("", TRUE));' string(13) "57d60ed86d339" string(23) "57d60ed86d33c9.09289803" ==== Chars used by "more entropy" ==== * More entropy uses digits and alphabets. Proposed implementation output example: $ ./php-bin -r 'var_dump(uniqid("", FALSE), uniqid("", TRUE));' string(13) "57d60f6bc6637" string(23) "57d60f6bc6654mb7167bnou" ===== Proposed PHP Version(s) ===== Next PHP (Currently PHP 7.2) ===== RFC Impact ===== ==== To SAPIs ==== None. ==== To Existing Extensions ==== None. ==== To Opcache ==== None. ==== New Constants ==== None. ==== php.ini Defaults ==== N/A ===== Open Issues ===== Make sure there are no open issues when the vote starts! ===== Unaffected PHP Functionality ===== Anything but uniqid() is affected. ===== Future Scope ===== None. ===== Proposed Voting Choices ===== State whether this project requires a 2/3 majority (see [[voting]]) * Yes * No ===== Patches and Tests ===== * https://github.com/php/php-src/pull/2123 ===== Implementation ===== After the project is implemented, this section should contain - the version(s) it was merged to - a link to the git commit(s) - a link to the PHP manual entry for the feature ===== References ===== Links to external references, discussions or RFCs ===== Rejected Features ===== Keep this updated with features that were discussed on the mail lists. ===== ChangeLog ===== * Made 2nd parameter a int