-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: align CUIDv2 generation with newest spec #16
Conversation
4d0e393
to
82c0fb4
Compare
Signed-off-by: Alan Brault <alan.brault@visus.io>
0cd72c0
to
bf7b745
Compare
bf7b745
to
5af41f7
Compare
Signed-off-by: Alan Brault <alan.brault@visus.io>
5af41f7
to
1dcfe90
Compare
@ericelliott I'd appreciate your input on these changes. I did not go forward with splitting the SHA3-512 byte array into smaller chunks before encoding. I was not comfortable with the potential loss of entropy or risks it could introduce. So, for now, It is unfortunate that .NET lacks strong built-in support for base conversions. They only support conversion of Base 2, 8, 10, and 16 and the performance of Obvservations It would have been nice if base-32 (z-base-32 variant) had been chosen instead of base-36 since it operates under powers-of-two. That would have resulted in much faster encoding as bitwise operations could have been done against the byte array instead of binary long division. |
BinaryPrimitives.WriteInt64LittleEndian(buffer, _t); | ||
BinaryPrimitives.WriteUInt32LittleEndian(buffer[..8], _c); | ||
BinaryPrimitives.WriteInt64LittleEndian(data[..8], _timestamp); | ||
BinaryPrimitives.WriteUInt64LittleEndian(data[^8..], _counter); | ||
|
||
Sha3Digest digest = new(512); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not familiar with this API, but new(512)
seems strange to me. new what? I'm expecting to see something like Sha3Digest digest = new Sha3Digest(512);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a C# 9 language feature called a new operator. I use explicit typing when I write code so instead of var digest = new Sha3Digest(512)
or Sha3Digest digest = new Sha3Digest(512)
I can do Sha3Digest digest = new(512)
instead since the type is known on the left side rather than the right side.
In my experience, this shouldn't be happening much in most apps. Typically, ids like this should be for entities that are getting persisted in a database. For use-cases that don't require persistence, maybe a simple counter would suffice, and the security and collision-resistance of Cuid2 would be overkill? Cuid2 is intentionally a little bit slow for security. The SHA-3 algorithm itself does extra hashing rounds for security, to prevent brute-force attacks. |
I considered that, but a 24-character Base36 value is 4x more collision-resistant than a 24-character Base32 value. |
Fair enough, as a baseline when I develop routines such as this, I push them to an upper limit (one million or more instances) as it's easier to identify any hidden bottlenecks. In this case, the slowest performer is the Base 36 encoding through |
Refactors code base to align it with the current CUIDv2 implementation. The following overall changes have occurred:
_c
->_counter
)System.Random
have been removed fromUtils.GenerateRandom()
Utils.GenerateIdentity()
has been refactored to use only the following parts:Utils.GenerateRandom()
Cuid2.Counter
was refactored:unsigned int
tounsigned long
476782367