make_id 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +28 -24
- data/lib/make_id/version.rb +1 -1
- data/lib/make_id.rb +45 -59
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2448e655a9a006abb23272b2b54c6b4fc537f702407c931afcf106b82c468b04
|
4
|
+
data.tar.gz: 9852758f34e12c2be8aa90149cdded09e011f2ab879320089fc1bfb3f577d849
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 108e40b61bfdcc00ac5e550b4afb14fb8f7298df617d10b7179975b2be8f6f04c6b4693fc6909de26f42e6a9977333d12f7ecc5c5846b1317b3ab728b6e6d04d
|
7
|
+
data.tar.gz: 25c7229af03bc353707c2ee832f00c2ad63243318156ffa51bcd197f328a2cae865eaf37fa0949d7c8d98bcf9e583b4ec8f2fb2563317d7584b906b9f3c8cf08
|
data/README.md
CHANGED
@@ -61,8 +61,14 @@ MakeId can return a random (8-byte by default) integer. You can request it retur
|
|
61
61
|
and with an optional check_digit.
|
62
62
|
Usually, you would use the integer returned, and call `int_to_base` to format for a URL or code.
|
63
63
|
|
64
|
-
MakeId.
|
65
|
-
MakeId.
|
64
|
+
MakeId.id() #=> 15379918763975837985ZZ
|
65
|
+
MakeId.id(base: 62, check_digit: true) #=> "2984biEwRT1"
|
66
|
+
|
67
|
+
Nano Id's are shorter unique strings generated from random characters, usually as a friendlier alternative
|
68
|
+
to UUID's. These are 8-byte numeric identifiers in extended bases, such as 36 or 62.
|
69
|
+
|
70
|
+
MakeId.nano_id() #=> "iZnLn96FVcjivEJA" (Base-62 be default)
|
71
|
+
MakeId.nano_id(base: 36) #=> "sf8kqb8ekn7k98rq"
|
66
72
|
|
67
73
|
### UUID
|
68
74
|
|
@@ -76,16 +82,28 @@ can be used to transform a long UUID into a possibly more palettable base repres
|
|
76
82
|
MakeId.uuid_to_base(u, 62) #=> "fWJtuXEQJnkjxroWjkmei" (21 characters)
|
77
83
|
|
78
84
|
Note that some databases support a UUID type which makes storing UUID's easier, and since they are stored as a binary
|
79
|
-
field, consume less space.
|
85
|
+
field, consume less space.
|
80
86
|
|
81
|
-
###
|
87
|
+
### Tokens
|
82
88
|
|
83
|
-
|
84
|
-
|
85
|
-
|
89
|
+
Tokens are randomly-generated strings of the character set of the requested base.
|
90
|
+
The default size is 16 characters of the Base-62 character set.
|
91
|
+
|
92
|
+
MakeId.token() #=> "Na4VX61PBFVZWL6Y"
|
93
|
+
MakeId.token(8, base:36) #=> "BK0ZTL9H"
|
94
|
+
|
95
|
+
### Codes
|
86
96
|
|
87
|
-
|
88
|
-
|
97
|
+
Codes are string tokens to send to users for input. They have no ambiguous characters to avoid confusion.
|
98
|
+
This is useful for verifications such as two-factor authentication codes, or license numbers.
|
99
|
+
This returns an 8-character string by default. Specify a group (size) and delimiter (default is a hyphen)
|
100
|
+
to make long codes readable.
|
101
|
+
|
102
|
+
MakeId.code #=> "22E0D18F"
|
103
|
+
MakeId.code(20) #=> "Y41Q24AG7DYZYTAZWQZX"
|
104
|
+
MakeId.code(20, group: 4, delimiter: "-") #=> "9975-V5VM-KKSR-4PQ6-7F4G"
|
105
|
+
|
106
|
+
### Temporal Identifiers
|
89
107
|
|
90
108
|
A `request_id` is a nano_id that can be used to track requests and jobs. It is a 16-byte string, the same
|
91
109
|
storage as a UUID, but with columnar values. The substring of 3 for 8 is a short (8 character) version that
|
@@ -96,9 +114,7 @@ can be used as well, is easier to read, sortable within a day, and unique enough
|
|
96
114
|
id[3,8] #=> "f1272t01"
|
97
115
|
#-------------------------->Hsssuuqq
|
98
116
|
|
99
|
-
|
100
|
-
|
101
|
-
Snowflakes were invented at Twitter to stamp an identifier for a tweet or direct message.
|
117
|
+
Snowflake Id's were invented at Twitter to stamp an identifier for a tweet or direct message.
|
102
118
|
It is an 8-byte integer intended to be time-sorted and unique across the fleet of servers saving messages.
|
103
119
|
It is a bit-mapped integer consisting of these parts:
|
104
120
|
|
@@ -137,18 +153,6 @@ records or when you need a slowflake ID but have a UUID column to fill.
|
|
137
153
|
MakeID.snowflake_datetime_uuid #=> "20240904-1418-5332-2000-3a38e61d5582"
|
138
154
|
#------------------------>YYYYMMDD-hhmm-ssuu-uwww-rrrrrrrrrrrr
|
139
155
|
|
140
|
-
## Experimental Id's
|
141
|
-
|
142
|
-
The `event_id` is a string, sortable by creation time, with visible time seperator columns.
|
143
|
-
It is of the format "YMDhmsuurrrr", using Base62, with an optional check_sum characer.
|
144
|
-
It also used the application epoch described under `snowflake_id`. "uu" represents the fractional
|
145
|
-
seconds that can be represented in Base62, and a 4-character random Base64 "nano_id".
|
146
|
-
|
147
|
-
MakeId.epoch = 2020
|
148
|
-
MakeId.event_id #=> "493KgpQGErTB"
|
149
|
-
#------------------->YMDhmsuurrrr ()
|
150
|
-
MakeId.event_id(check_digit: true) #=> "493Kkha6HZa2" (3 random chars + check digit)
|
151
|
-
|
152
156
|
## Development
|
153
157
|
|
154
158
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/lib/make_id/version.rb
CHANGED
data/lib/make_id.rb
CHANGED
@@ -73,24 +73,11 @@ module MakeId
|
|
73
73
|
end
|
74
74
|
|
75
75
|
##############################################################################
|
76
|
-
#
|
77
|
-
##############################################################################
|
78
|
-
|
79
|
-
# Returns a random alphanumeric string of the given base, default of 62.
|
80
|
-
# Base 64 uses URL-safe characters. Bases 19-32 and below use a special
|
81
|
-
# character set that avoids visually ambiguous characters. Other bases
|
82
|
-
# utilize the full alphanumeric characer set (digits, lower/upper letters).
|
83
|
-
def self.random(size = 16, base: 62, chars: nil)
|
84
|
-
_, chars = base_characters(base, chars)
|
85
|
-
SecureRandom.alphanumeric(size, chars: chars.chars)
|
86
|
-
end
|
87
|
-
|
88
|
-
##############################################################################
|
89
|
-
# Integers
|
76
|
+
# Numeric Identifiers (of any suported base)
|
90
77
|
##############################################################################
|
91
78
|
|
92
79
|
# Random Integer ID
|
93
|
-
def self.
|
80
|
+
def self.id(bytes: 8, base: 10, absolute: true, check_digit: false)
|
94
81
|
id = SecureRandom.random_number(2**(bytes * 8) - 2) + 1 # +1 to avoid zero
|
95
82
|
id = id.abs if absolute
|
96
83
|
id = int_to_base(id, base) unless base == 10
|
@@ -98,17 +85,26 @@ module MakeId
|
|
98
85
|
id
|
99
86
|
end
|
100
87
|
|
101
|
-
def self.
|
102
|
-
id =
|
103
|
-
pass =
|
88
|
+
def self.id_password(bytes: 8, base: 10, absolute: true, alpha: nil)
|
89
|
+
id = id(bytes: bytes)
|
90
|
+
pass = id(bytes: 16)
|
104
91
|
[int_to_base(id, base), encode_alphabet(pass, alpha || BASE94, seed: id)]
|
105
92
|
end
|
106
93
|
|
94
|
+
# Generates a 8-byte "nano id", a string of random characters of the given alphabet,
|
95
|
+
# suitable for URL's or where you don't want to show a sequential number.
|
96
|
+
# A check digit can be added to the end to help prevent typos.
|
97
|
+
def self.nano_id(bytes: 8, base: 62, check_digit: true)
|
98
|
+
bytes -= 1 if check_digit
|
99
|
+
id = id(bytes: bytes, base: base)
|
100
|
+
check_digit ? append_check_digit(id, base) : id
|
101
|
+
end
|
102
|
+
|
107
103
|
##############################################################################
|
108
104
|
# UUID - Universally Unique Identifier
|
109
105
|
##############################################################################
|
110
106
|
|
111
|
-
# Returns a
|
107
|
+
# Returns a 16-byte securely-random generated UUID v4
|
112
108
|
def self.uuid
|
113
109
|
SecureRandom.uuid
|
114
110
|
end
|
@@ -121,49 +117,40 @@ module MakeId
|
|
121
117
|
end
|
122
118
|
|
123
119
|
##############################################################################
|
124
|
-
#
|
120
|
+
# Strings Identifiers
|
125
121
|
##############################################################################
|
126
122
|
|
127
|
-
#
|
128
|
-
#
|
129
|
-
#
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
check_digit ? append_check_digit(id, base) : id
|
135
|
-
end
|
136
|
-
|
137
|
-
# Given a nano_id, replaces visually ambiguous characters and verifies the
|
138
|
-
# check digit. Returns the corrected id or nil if the check digit is invalid.
|
139
|
-
def self.verify_base32_id(nanoid)
|
140
|
-
nanoid.gsub!(/[oO]/, "0")
|
141
|
-
nanoid.gsub!(/[lLiI]/, "1")
|
142
|
-
nanoid.downcase
|
143
|
-
valid_check_digit?(nanoid, base: 32)
|
123
|
+
# Returns a random alphanumeric string of the given base, default of 62.
|
124
|
+
# Base 64 uses URL-safe characters. Bases 19-32 and below use a special
|
125
|
+
# character set that avoids visually ambiguous characters. Other bases
|
126
|
+
# utilize the full alphanumeric characer set (digits, lower/upper letters).
|
127
|
+
def self.token(size = 16, base: 62, chars: nil)
|
128
|
+
_, chars = base_characters(base, chars)
|
129
|
+
SecureRandom.alphanumeric(size, chars: chars.chars)
|
144
130
|
end
|
145
131
|
|
146
|
-
#
|
147
|
-
#
|
148
|
-
#
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
nano_id(size: size, base: base, check_digit: check_digit).upcase
|
132
|
+
# Returns a new, ramdonly-generated Base-32 code (no ambiguous characters).
|
133
|
+
# Use this for Two-Factor Authorization, and serial number codes to be
|
134
|
+
# input by users. Use verify_code() to "fix" user-input of codes.
|
135
|
+
def self.code(size = 8, group: 0, delimiter: "-")
|
136
|
+
id = token(size, base: 32)
|
137
|
+
id = id.chars.each_slice(group).map(&:join).join(delimiter) if group > 0
|
138
|
+
id
|
154
139
|
end
|
155
140
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
141
|
+
# Given a nano_id, replaces visually ambiguous characters and verifies the
|
142
|
+
# check digit. Returns the corrected id or nil if the check digit is invalid.
|
143
|
+
def self.verify_code(nanoid, check_digit: false)
|
144
|
+
nanoid = nanoid.gsub(/\W/, "")
|
145
|
+
nanoid = nanoid.gsub(/[oO]/, "0")
|
146
|
+
nanoid = nanoid.gsub(/[lLiI]/, "1")
|
147
|
+
nanoid = nanoid.upcase
|
148
|
+
return valid_check_digit?(nanoid, base: 32) if check_digit
|
149
|
+
nanoid
|
163
150
|
end
|
164
151
|
|
165
152
|
##############################################################################
|
166
|
-
# TEMPORAL
|
153
|
+
# TEMPORAL Identifiers
|
167
154
|
##############################################################################
|
168
155
|
|
169
156
|
# Event Id - A nano_id, but timestamped event identifier: YMDHMSUUrrrrc
|
@@ -180,7 +167,7 @@ module MakeId
|
|
180
167
|
usec.rjust(2, "0") # 2-chars, 0..3843
|
181
168
|
]
|
182
169
|
nano_size = size - 8 - (check_digit ? 1 : 0)
|
183
|
-
parts <<
|
170
|
+
parts << token(nano_size, base: 62) if nano_size > 0
|
184
171
|
id = check_digit ? append_check_digit(parts.join, 62) : parts.join
|
185
172
|
id[0, size]
|
186
173
|
end
|
@@ -206,7 +193,7 @@ module MakeId
|
|
206
193
|
int_to_base((time.subsec.to_f * 32 * 32).to_i, 32), # 2 chars
|
207
194
|
sequence.to_s(32).rjust(2, "0"), # 2 chars "-",
|
208
195
|
(app_worker_id % 1024).to_s(32).rjust(2, "0"), # 2 chars
|
209
|
-
|
196
|
+
token(3, base: 32)
|
210
197
|
].join
|
211
198
|
end
|
212
199
|
|
@@ -323,7 +310,7 @@ module MakeId
|
|
323
310
|
|
324
311
|
# Parses a string as a base n number and returns its decimal integer value
|
325
312
|
def self.base_to_int(string, base = 62, check_digit: false)
|
326
|
-
# TODO check_digit
|
313
|
+
# TODO: check_digit
|
327
314
|
_, chars = base_characters(base, chars)
|
328
315
|
decode_alphabet(string, chars)
|
329
316
|
end
|
@@ -367,9 +354,7 @@ module MakeId
|
|
367
354
|
else
|
368
355
|
chars = BASE62[0..(base - 1)]
|
369
356
|
end
|
370
|
-
if shuffle_seed
|
371
|
-
chars = chars.chars.shuffle(random: Random.new(shuffle_seed)).join
|
372
|
-
end
|
357
|
+
chars = chars.chars.shuffle(random: Random.new(shuffle_seed)).join if shuffle_seed
|
373
358
|
base = chars.size
|
374
359
|
|
375
360
|
[base, chars]
|
@@ -389,6 +374,7 @@ module MakeId
|
|
389
374
|
# Uses a pre-defined check_proc if configured. See check_proc=().
|
390
375
|
def self.compute_check_digit(id, base = 10)
|
391
376
|
return @@check_proc.call(id, base) if @@check_proc.is_a?(Proc)
|
377
|
+
|
392
378
|
int_to_base(Zlib.crc32(id.to_s) % base, base)
|
393
379
|
end
|
394
380
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: make_id
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Allen Fair
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-11-
|
11
|
+
date: 2024-11-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: base64
|