-
-
Notifications
You must be signed in to change notification settings - Fork 531
Description
UUID v4 generation bug: variant bits always resolve to 8
Problem Description
The current UUID v4 generation logic contains a subtle bug where a bitwise operation is applied to a string value.
Because of JavaScript’s implicit type coercion, this causes the UUID variant field to always be set to "8" instead of being randomly selected from "8" | "9" | "a" | "b" as required by RFC 4122.
This does not throw an error and produces valid-looking UUIDs, but it silently reduces randomness and Much higher chance of duplicate IDs may lead to collisions and data consistency issues in distributed or offline-first scenarios.
Affected Code
Affected Code
The issue occurs at line 32 in the UUID generation function:
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);
At this line, a bitwise operation is performed directly on s[19], which is a string value representing a hexadecimal character.
Because JavaScript bitwise operators only work on numbers, the string is implicitly coerced into a numeric value. For non-numeric hexadecimal characters ("a"–"f"), this coercion results in NaN, which is then treated as 0 during the bitwise operation. As a result, the expression always resolves to the same value, causing the UUID variant to be fixed to "8" instead of being randomly selected from the valid set (8, 9, a, b).
Proposed Solution (Conceptual)
Before applying any bitwise operations, the hexadecimal character at position 19 should first be explicitly converted into its numeric (base-16) representation. Once the value is a number, the variant bits can be correctly masked and set according to the UUID v4 specification. The resulting numeric value can then be converted back into a hexadecimal character.
This preserves:
- Correct UUID v4 variant behavior
- Proper randomness
- Compatibility with RFC 4122 and strict validators