[wp-trac] [WordPress Trac] #59239: wp_generate_uuid4 collisions

WordPress Trac noreply at wordpress.org
Sun Mar 15 06:28:46 UTC 2026


#59239: wp_generate_uuid4 collisions
-------------------------------------+---------------------
 Reporter:  joppuyo                  |       Owner:  (none)
     Type:  defect (bug)             |      Status:  new
 Priority:  normal                   |   Milestone:  7.0
Component:  General                  |     Version:
 Severity:  normal                   |  Resolution:
 Keywords:  has-patch needs-testing  |     Focuses:
-------------------------------------+---------------------

Comment (by alexodiy):

 Tested PR [https://github.com/WordPress/wordpress-develop/pull/10694
 #10694] on PHP 8.5.1 (NTS, Windows x64) against trunk at r62029.

 == Environment ==

 * PHP: 8.5.1 (cli) NTS Visual C++ 2022 x64
 * WordPress: 7.0-beta5 (trunk r62029)
 * OS: Windows 11

 == Reproduction ==

 Demonstrated the collision problem by generating UUIDs with `mt_rand()`
 using repeated seeds. Since `mt_rand()` uses a 32-bit seed, identical
 seeds produce identical UUID sequences.

 '''Before patch (mt_rand):'''

 {{{
 mt_srand(12345);
 $uuid1 = wp_generate_uuid4(); // 51e22de5-fd1d-4881-8da4-ada90ffe517e

 mt_srand(12345);
 $uuid2 = wp_generate_uuid4(); // 51e22de5-fd1d-4881-8da4-ada90ffe517e

 // $uuid1 === $uuid2 → collision
 }}}

 Generated 131,072 UUIDs with 65,536 sequential seeds across 2 rounds.
 Result: 65,536 unique UUIDs, '''65,536 collisions''' (every UUID from
 round 2 collided with round 1).

 '''After patch (wp_rand / random_int):'''

 Generated 100,000 UUIDs using `random_int()` (which `wp_rand()` delegates
 to). Result: 100,000 unique UUIDs, '''0 collisions'''.

 == UUID4 format validation ==

 Verified 1,000 UUIDs generated with the patched function:

 * All 1,000 match the UUID4 regex
 `^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$`
 * Version nibble (position 13) is always `4`
 * Variant nibble (position 17) is always `8`, `9`, `a`, or `b`

 Bitwise operations `| 0x4000` and `| 0x8000` are correctly preserved after
 switching from `mt_rand()` to `wp_rand()`.

 == Results ==

 ||= Scenario =||= Before Patch (mt_rand) =||= After Patch (wp_rand) =||
 || Same seed produces same UUID || Yes (collision) || N/A (CSPRNG, no seed
 control) ||
 || 131K UUIDs with repeated seeds || 65,536 collisions || 0 collisions in
 100K ||
 || UUID4 format valid || Yes || Yes ||
 || Version/variant bits correct || Yes || Yes ||

 Patch is minimal and correct. No regressions. +1 for commit.

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/59239#comment:8>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list