Module: Familia::SecureIdentifier
- Included in:
- Familia
- Defined in:
- lib/familia/secure_identifier.rb
Constant Summary collapse
- HEX_LENGTHS =
Fast lookup for hex (base 16) - our most common case Avoids calculation overhead for 99% of ID generation
{ 256 => 64, # SHA-256 equivalent entropy 128 => 32, # UUID equivalent entropy 64 => 16, # Compact ID }.freeze
Class Method Summary collapse
-
.min_length_for_bits(bits, base) ⇒ Integer
Get minimum character length needed to encode
bits
of entropy inbase
.
Instance Method Summary collapse
-
#generate_hex_id ⇒ String
Generates a 256-bit cryptographically secure hexadecimal identifier.
-
#generate_hex_trace_id ⇒ String
Generates a 64-bit cryptographically secure hexadecimal trace identifier.
-
#generate_id(base = 36) ⇒ String
Generates a cryptographically secure identifier, encoded in the specified base.
-
#generate_trace_id(base = 36) ⇒ String
Generates a short, secure trace identifier, encoded in the specified base.
-
#shorten_to_external_id(hex_id, base: 36) ⇒ String
Truncates a 256-bit hexadecimal ID to 128 bits and encodes it in a given base.
-
#shorten_to_trace_id(hex_id, base: 36) ⇒ String
Truncates a 256-bit hexadecimal ID to 64 bits and encodes it in a given base.
Class Method Details
.min_length_for_bits(bits, base) ⇒ Integer
Get minimum character length needed to encode bits
of entropy in base
122 123 124 125 126 127 |
# File 'lib/familia/secure_identifier.rb', line 122 def self.min_length_for_bits(bits, base) return HEX_LENGTHS[bits] if base == 16 && HEX_LENGTHS.key?(bits) @length_cache ||= {} @length_cache[[bits, base]] ||= (bits * Math.log(2) / Math.log(base)).ceil end |
Instance Method Details
#generate_hex_id ⇒ String
Generates a 256-bit cryptographically secure hexadecimal identifier.
12 13 14 |
# File 'lib/familia/secure_identifier.rb', line 12 def generate_hex_id SecureRandom.hex(32) end |
#generate_hex_trace_id ⇒ String
64 bits provides ~18 quintillion values, sufficient for request tracing.
Generates a 64-bit cryptographically secure hexadecimal trace identifier.
20 21 22 |
# File 'lib/familia/secure_identifier.rb', line 20 def generate_hex_trace_id SecureRandom.hex(8) end |
#generate_id(base = 36) ⇒ String
Generates a cryptographically secure identifier, encoded in the specified base. By default, this creates a compact, URL-safe base-36 string.
36 37 38 39 |
# File 'lib/familia/secure_identifier.rb', line 36 def generate_id(base = 36) target_length = SecureIdentifier.min_length_for_bits(256, base) generate_hex_id.to_i(16).to_s(base).rjust(target_length, '0') end |
#generate_trace_id(base = 36) ⇒ String
Generates a short, secure trace identifier, encoded in the specified base. Suitable for tracing, logging, and other ephemeral use cases.
53 54 55 56 |
# File 'lib/familia/secure_identifier.rb', line 53 def generate_trace_id(base = 36) target_length = SecureIdentifier.min_length_for_bits(64, base) generate_hex_trace_id.to_i(16).to_s(base).rjust(target_length, '0') end |
#shorten_to_external_id(hex_id, base: 36) ⇒ String
This is useful for creating shorter, public-facing IDs from secure internal ones.
Truncates a 256-bit hexadecimal ID to 128 bits and encodes it in a given base. This function takes the most significant bits from the hex string to maintain randomness while creating a shorter, deterministic identifier that’s safe for outdoor use.
87 88 89 90 91 |
# File 'lib/familia/secure_identifier.rb', line 87 def shorten_to_external_id(hex_id, base: 36) target_length = SecureIdentifier.min_length_for_bits(128, base) truncated = hex_id.to_i(16) >> (256 - 128) # Always 128 bits truncated.to_s(base).rjust(target_length, '0') end |
#shorten_to_trace_id(hex_id, base: 36) ⇒ String
Truncates a 256-bit hexadecimal ID to 64 bits and encodes it in a given base. These short, deterministic IDs are useful for secure logging. By inputting the full hexadecimal string, you can generate a consistent short ID that allows tracking an entity through logs without exposing the entity’s full identifier..
66 67 68 69 70 |
# File 'lib/familia/secure_identifier.rb', line 66 def shorten_to_trace_id(hex_id, base: 36) target_length = SecureIdentifier.min_length_for_bits(64, base) truncated = hex_id.to_i(16) >> (256 - 64) # Always 64 bits truncated.to_s(base).rjust(target_length, '0') end |