This gem provides uniq and random ids generation in distributed services but at the same time gives some ordering (timestamp) and debug (context) information
The gem is inspired by Twitter Snowflake and other algorithms.
The main difference is that ids generated by gem are not fully sequenced. We want to have large random part that can be used as a simple guard against enumeration attack.
While we designed format and gem we used these as requirements:
- Every system should be able to independently (without coordination) generate id that will never (with reasonable chances) be duplicated
- ID allows partial time ordering (timestamp in seconds)
- ID has easy system identifier (context)
- ID is human readable
- ID size is not a concern
- ID format should not be used for business/application logic - thus it remains flexible for future changes
Suggested algorithm is based on the Twitter snowflake and other similar alghorithms:
TTTTTTTT-II-RRRRRRRRRRRRRRRRRRRRRR
TTTTTTTT
- time in seconds since 2000 (just cool number) represented as hex - Gives us ~150 years of uniq sequencesII
- 1 byte for System Identification in hexRRRRRRRRRRRRRRRRRRRRRR
- 11 bytes secure random number as hex
Code to generate is pretty straightforward:
time = format('%08x', Time.now.to_i - Time.new(2000).to_i)
id = '6a'
random = SecureRandom.hex(11)
id = "#{time}-#{id}-#{random}" # "21dc3680-6a-910df0665e5e29b9f89e21"
Add gem to your application's Gemfile:
gem 'id_generator'
# Somewhere during project start
context_id = 165 # value from 0 to 255
IdGenerator.configuration.context_id = context_id
# Or using block
IdGenerator.configure { |config| config.context_id = context_id }
#Inside of the actual code
IdGenerator.generate
Bug reports and pull requests are welcome on GitHub at https://github.com/matic-insurance/id_generator.
The gem is available as open source under the terms of the MIT License.