Module: ULID::Generate

Includes:
Constants
Included in:
Identifier
Defined in:
lib/ulid/generate.rb

Constant Summary

Constants included from Constants

Constants::B32REF, Constants::ENCODING, Constants::MAX_ENTROPY, Constants::MAX_TIME, Constants::MIN_ENTROPY, Constants::MIN_TIME

Instance Method Summary collapse

Instance Method Details

#encode32Object

returns the binary ULID as Base32 encoded string.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/ulid/generate.rb', line 10

def encode32
  # Optimized unrolled loop ahead.
  # From https://github.com/RobThree/NUlid
  # via https://github.com/oklog/ulid/blob/c3c01856f7e43fa64133819126887124d5f05e39/ulid.go#L154

  id = @bytes.bytes

  output = ''

  # Base32 encodes 5 bits of each byte of the input in each byte of the
  # output. That means each input byte produces >1 output byte and some
  # output bytes encode parts of multiple input bytes.
  #
  # The end result is a human / URL friendly output string that can be
  # decoded into the original bytes.

  # 10 byte timestamp
  output << ENCODING[(id[0]&224)>>5]
  output << ENCODING[id[0]&31]
  output << ENCODING[(id[1]&248)>>3]
  output << ENCODING[((id[1]&7)<<2)|((id[2]&192)>>6)]
  output << ENCODING[(id[2]&62)>>1]
  output << ENCODING[((id[2]&1)<<4)|((id[3]&240)>>4)]
  output << ENCODING[((id[3]&15)<<1)|((id[4]&128)>>7)]
  output << ENCODING[(id[4]&124)>>2]
  output << ENCODING[((id[4]&3)<<3)|((id[5]&224)>>5)]
  output << ENCODING[id[5]&31]

  # 16 bytes of entropy
  output << ENCODING[(id[6]&248)>>3]
  output << ENCODING[((id[6]&7)<<2)|((id[7]&192)>>6)]
  output << ENCODING[(id[7]&62)>>1]
  output << ENCODING[((id[7]&1)<<4)|((id[8]&240)>>4)]
  output << ENCODING[((id[8]&15)<<1)|((id[9]&128)>>7)]
  output << ENCODING[(id[9]&124)>>2]
  output << ENCODING[((id[9]&3)<<3)|((id[10]&224)>>5)]
  output << ENCODING[id[10]&31]
  output << ENCODING[(id[11]&248)>>3]
  output << ENCODING[((id[11]&7)<<2)|((id[12]&192)>>6)]
  output << ENCODING[(id[12]&62)>>1]
  output << ENCODING[((id[12]&1)<<4)|((id[13]&240)>>4)]
  output << ENCODING[((id[13]&15)<<1)|((id[14]&128)>>7)]
  output << ENCODING[(id[14]&124)>>2]
  output << ENCODING[((id[14]&3)<<3)|((id[15]&224)>>5)]
  output << ENCODING[id[15]&31]

  output
end

#millisecond_timeObject



63
64
65
# File 'lib/ulid/generate.rb', line 63

def millisecond_time
  (@time.to_r * 1_000).to_i
end

#random_bytesObject



59
60
61
# File 'lib/ulid/generate.rb', line 59

def random_bytes
  SecureRandom.random_bytes(10)
end

#time_bytesObject

THIS IS CORRECT (to the ULID spec)



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/ulid/generate.rb', line 68

def time_bytes
  id = []

  t = millisecond_time

  # via https://github.com/oklog/ulid/blob/c3c01856f7e43fa64133819126887124d5f05e39/ulid.go#L295
  id << [t >> 40].pack('c')
  id << [t >> 32].pack('c')
  id << [t >> 24].pack('c')
  id << [t >> 16].pack('c')
  id << [t >> 8].pack('c')
  id << [t].pack('c')

  id.join
end