Correct ULID predictability & consider adding DistributedId & DistributedId128
Greetings! My compliments on the beautiful comparison.
For ULID, predictability is marked as "low" (i.e. good), but I think that misses an important caveat: If multiple ULIDs are generated by one application instance on the same millisecond, then they use increments of 1. That messes with the unpredictability, big time.
Say that you are a tenant for a product that uses ULIDs. For any ID that you know of, increment it by 1 and see if the result exists. Use timing attacks to make this extra potent. There is a good chance that things were processed either in batch or under high concurrency, and that you are able to guess a ULID of something belonging to another tenant. Bye-bye unpredictability.
Two identities that are missing and that do provide both monotonicity and unpredictability even intra-millisecond are DistributedId and DistributedId128. The former has a custom format and the latter is an improved UUIDv7 variant.
They can be represented in various forms, so the example field could show something like 1088824355131185736905670087 / 3zfAkCP7ZtzfeQYp and