Add Cuid2 Support
This adds Cuid2 support and database tests, non breaking changes for existing supported id generation methods, also adds a config to modify the length of the generated Cuid2. This adds helper methods for the Blueprint schema builder including updating foreignIdFor and defaultMorphKeyType to support Cuid2, and this adds an Str::isCuid method for validating a valid Cuid2.
Cuid2 offers secure, collision-resistant ids optimized for horizontal scaling and performance.
Cuid2 is:
- Secure: It's not feasible to guess the next id, existing valid ids, or learn anything about the referenced data from the id. Cuid2 uses multiple, independent entropy sources and hashes them with a security-audited, NIST-standard cryptographically secure hashing algorithm (Sha3).
- Collision resistant: It's extremely unlikely to generate the same id twice (by default, you'd need to generate roughly 4,000,000,000,000,000,000 ids (sqrt(36^(24-1) * 26) = 4.0268498e+18) to reach 50% chance of collision.)
- Horizontally scalable: Generate ids on multiple machines without coordination.
- Offline-compatible: Generate ids without a network connection.
- URL and name-friendly: No special characters.
- Fast and convenient: No async operations. Won't introduce user-noticeable delays. Less than 5k, gzipped.
- But not too fast: If you can hash too quickly you can launch parallel attacks to find duplicates or break entropy-hiding. For unique ids, the fastest runner loses the security race.
The visus/cuid2 package is used for CUID generation, and it requires the gmp php extension.
Thanks for submitting a PR!
Note that draft PR's are not reviewed. If you would like a review, please mark your pull request as ready for review in the GitHub user interface.
Pull requests that are abandoned in draft may be closed due to inactivity.
It looks like a good separate integration package. Here is an example: https://github.com/cybercog/laravel-optimus
CUID2 values are a real bad primary key for MySQL - which is the most used database with Laravel. And using it as primary key would be the obvious use case. The problem is that MySQL is really slow when the primary key is in random order - you can find tones of information about it.
I am therefore against this change, as it would result in many slow Laravel applications thinking to adopt this who don't know of the implications.
I don't see any reason why this can't be released as a package and then used by developers who really know what they are doing.
CUID2 values are a real bad primary key for MySQL - which is the most used database with Laravel. And using it as primary key would be the obvious use case. The problem is that MySQL is really slow when the primary key is in random order - you can find tones of information about it.
I am therefore against this change, as it would result in many slow Laravel applications thinking to adopt this who don't know of the implications.
I don't see any reason why this can't be released as a package and then used by developers who really know what they are doing.
I feel like this argument is always used if you see anything other than int. I'm not for or against adding custom id support but majority of apps won't even reach 1mil entries which it doesn't matter at that point random or not, and if you use UUIDv7 or something else than v4 MySQL is pain in the ass to use it with anyway. Also Laravel uses string UUIDv4 for notifications by default, wouldn't that also not imply bad performance for a table that most of the time would have more entries than the whole database combined for most apps?
Also Laravel uses string UUIDv4 for notifications by default, wouldn't that also not imply bad performance for a table that most of the time would have more entries than the whole database combined for most apps?
Yes. But I didn't see this change before it went live. Otherwise I would have said the same. But its not too late to change.
Another problem with cuid2 is that the there are constantly new identifiers invented - we can't add them all. And until today, cuid2 has no real widespread usage in the PHP/Laravel world compared to e.g. UUIDs.
Another problem with cuid2 is that the there are constantly new identifiers invented - we can't add them all. And until today, cuid2 has no real widespread usage in the PHP/Laravel world compared to e.g. UUIDs.
On that I do agree. In any case, random id's all have a place when it comes to security, and I've played around with Cuid2 on MySQL yesterday where even with 46mil row table the insert and read is still within acceptable range, where insert is <20ms and read is as fast as anything else not int related and that amount of entries is to dream for for 99% of apps.