uuid-ncname 0.2.6 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f82febb1e1498f1d602bd2225b730b7e9128b7ea7b811472465001ae9925e83d
4
- data.tar.gz: 8f403882f98f9509c074e3b53c1aebe58ff0b0adbe9f248baf4df9ded59b7b25
3
+ metadata.gz: 5949f2dc85dabebd7eca564905e35a5e81c9c0d28b5801f4796c07ab177035fe
4
+ data.tar.gz: 8d8fc2c39629b9135e7fbd36d6395a638e5a88f64cea7b09ba78c832d8a9eb08
5
5
  SHA512:
6
- metadata.gz: b0c1948dd81504cd7241f2a5ad78e50f661b4d9b0868402fd3e393760a5ddf6d30be82f39b51d700e0ded7681efa65134fb0e37ffa27f2108c238ccb8d2cbdfe
7
- data.tar.gz: 2c86dfc2b5ee4b1c1be7c1e8343e844bfa9df0a94ebf20b487fd5988b53df4e138ae05e44d5134b00c4e1092140d24042c3e1c5d90ad9238a87fea65ab165f3c
6
+ metadata.gz: 749c76afe8ca6edc6fc563b8496c97a1c25bcaa956c287181d039b219da25d196ea9d9b2736ecd8f7a81645bc82cc835ddf0d0062f40817dc038e5011833d265
7
+ data.tar.gz: 429ec2d8d45e7815fd775d03ce9c327996321f44dd3ef7a0cf6e880c161ed07fd9f513249f6e16961e7b3d84af043bc55080ba1d4ced8fa64a46f22b4eab7f9a
data/.gitignore CHANGED
@@ -8,6 +8,8 @@ syntax: glob
8
8
  /spec/reports/
9
9
  /tmp/
10
10
  *.gem
11
+ \#*
12
+ .\#*
11
13
 
12
14
  # rspec failure tracking
13
15
  .rspec_status
@@ -0,0 +1,5 @@
1
+ --protected
2
+ --no-private
3
+ --hide-void-return
4
+ --markup markdown
5
+ --readme README.md
@@ -3,11 +3,20 @@ require "uuid/ncname/version"
3
3
 
4
4
  require 'base64'
5
5
  require 'base32'
6
+ require 'base58'
6
7
 
7
8
  module UUID::NCName
8
9
 
9
10
  private
10
11
 
12
+ MATCH = /^([A-Pa-p]) # zero-width boundary and version bookend
13
+ ([2-7A-Za-z]{24}|[-0-9A-Z_a-z]{20}| # base32 and 64
14
+ (?:[1-9A-HJ-NP-Za-z]{15}_{6}|[1-9A-HJ-NP-Za-z]{16}_{5}|
15
+ [1-9A-HJ-NP-Za-z]{17}_{4}|[1-9A-HJ-NP-Za-z]{18}___|
16
+ [1-9A-HJ-NP-Za-z]{19}__|[1-9A-HJ-NP-Za-z]{20}_|
17
+ [1-9A-HJ-NP-Za-z]{21})) # base58 with underscore pad
18
+ ([-0-9A-Z_a-z])$/x.freeze # lax variant bookend and zero-width boundary
19
+
11
20
  ENCODE = {
12
21
  32 => -> (bin, align = true) {
13
22
  if align
@@ -18,7 +27,15 @@ module UUID::NCName
18
27
 
19
28
  out = ::Base32.encode bin
20
29
 
21
- out.downcase[0, 25]
30
+ out.downcase[0, 25] # clip off the padding
31
+ },
32
+ 58 => -> (bin, _) {
33
+ variant = bin[-1].ord >> 4
34
+ # note the bitcoin alphabet is the one used in draft-msporny-base58
35
+ out = ::Base58.binary_to_base58(bin.chop, :bitcoin)
36
+ # we need to pad base58 with underscores because it is variable length
37
+ out + (?_ * (21 - out.length)) +
38
+ encode_version(variant) # encode_version does variant too
22
39
  },
23
40
  64 => -> (bin, align = true) {
24
41
  if align
@@ -29,10 +46,11 @@ module UUID::NCName
29
46
 
30
47
  out = ::Base64.urlsafe_encode64 bin
31
48
 
32
- out[0, 21]
49
+ out[0, 21] # clip off the padding
33
50
  },
34
51
  }
35
52
 
53
+ # note the version symbol is already removed
36
54
  DECODE = {
37
55
  32 => -> (str, align = true) {
38
56
  str = str.upcase[0, 25] + 'A======'
@@ -41,6 +59,11 @@ module UUID::NCName
41
59
 
42
60
  out.pack 'C*'
43
61
  },
62
+ 58 => -> (str, _) {
63
+ variant = decode_version(str[-1]) << 4
64
+ str = str.chop.tr ?_, ''
65
+ ::Base58.base58_to_binary(str, :bitcoin) + variant.chr
66
+ },
44
67
  64 => -> (str, align = true) {
45
68
  str = str[0, 21] + 'A=='
46
69
  out = ::Base64.urlsafe_decode64(str).unpack 'C*'
@@ -116,7 +139,7 @@ module UUID::NCName
116
139
  ],
117
140
  ]
118
141
 
119
- def self.encode_version version, radix
142
+ def self.encode_version version, radix = 64
120
143
  offset = radix == 32 ? 97 : 65
121
144
  ((version & 15) + offset).chr
122
145
  end
@@ -170,7 +193,7 @@ module UUID::NCName
170
193
  # @param radix [32, 64] either the number 32 or the number 64.
171
194
  #
172
195
  # @param version [0, 1] An optional formatting version, where 0 is
173
- # the naïve original version and 1 moves the +variant+ nybble out
196
+ # the naïve original version and 1 moves the `variant` nybble out
174
197
  # to the end of the identifier. You will be warned for the time
175
198
  # being if you do not set this parameter explicitly. The default
176
199
  # version is 1.
@@ -182,15 +205,16 @@ module UUID::NCName
182
205
  # Base64, the overhang is only ever 4 bits. This means that when
183
206
  # the terminating character is aligned, it will always be in the
184
207
  # range of the letters A through P in (the RFC 3548/4648
185
- # representations of) both Base32 and Base64. When +version+ is 1
208
+ # representations of) both Base32 and Base64. When `version` is 1
186
209
  # and the terminating character is aligned, RFC4122-compliant UUIDs
187
- # will always terminate with +I+, +J+, +K+, or +L+. Defaults to
188
- # +true+.
210
+ # will always terminate with `I`, `J`, `K`, or `L`. Defaults to
211
+ # `true`.
189
212
  #
190
213
  # @return [String] The NCName-formatted UUID.
191
-
214
+ #
192
215
  def self.to_ncname uuid, radix: 64, version: nil, align: true
193
- raise 'Radix must be either 32 or 64' unless [32, 64].include? radix
216
+ raise 'Radix must be either 32, 58, or 64' unless
217
+ [32, 58, 64].include? radix
194
218
  raise 'UUID must be something stringable' if uuid.nil? or
195
219
  not uuid.respond_to? :to_s
196
220
  align = !!align # coerce to a boolean
@@ -233,12 +257,12 @@ module UUID::NCName
233
257
  # @param radix [nil, 32, 64] Optional radix; will use heuristic if omitted.
234
258
  #
235
259
  # @param format [:str, :hex, :b64, :bin] An optional formatting
236
- # parameter; defaults to +:str+, the canonical string representation.
260
+ # parameter; defaults to `:str`, the canonical string representation.
237
261
  #
238
262
  # @param version [0, 1] See ::to_ncname. Defaults to 1.
239
263
  #
240
264
  # @param align [nil, true, false] See ::to_ncname for details.
241
- # Setting this parameter to +nil+, the default, will cause the
265
+ # Setting this parameter to `nil`, the default, will cause the
242
266
  # decoder to detect the alignment state from the identifier.
243
267
  #
244
268
  # @param validate [false, true] Check that the ninth (the variant)
@@ -246,7 +270,7 @@ module UUID::NCName
246
270
  #
247
271
  # @return [String, nil] The corresponding UUID or nil if the input
248
272
  # is malformed.
249
-
273
+ #
250
274
  def self.from_ncname ncname,
251
275
  radix: nil, format: :str, version: nil, align: nil, validate: false
252
276
  raise 'Format must be symbol-able' unless format.respond_to? :to_sym
@@ -260,29 +284,25 @@ module UUID::NCName
260
284
  return unless ncname and ncname.respond_to? :to_s
261
285
 
262
286
  ncname = ncname.to_s.strip.gsub(/\s+/, '')
263
- match = /^([A-Za-z])([0-9A-Za-z_-]{21,})$/.match(ncname) or return
287
+ match = MATCH.match(ncname) or return
288
+ return if align and !/[A-Pa-p]$/.match? ncname # MATCH is lax
264
289
 
290
+ # determine the radix from the input
265
291
  if radix
266
- raise "Radix must be 32 or 64, not #{radix}" unless [32, 64].any? radix
267
- return unless { 32 => 26, 64 => 22 }[radix] == ncname.length
292
+ raise ArgumentError, "Radix must be 32, 58, or 64, not #{radix}" unless
293
+ [32, 58, 64].any? radix
294
+ return unless { 32 => 26, 58 => 23, 64 => 22 }[radix] == ncname.length
268
295
  else
269
- len = ncname.length
270
-
271
- if ncname =~ /[_-]/
272
- radix = 64
273
- elsif len >= 26
274
- radix = 32
275
- elsif len >= 22
276
- radix = 64
277
- else
278
- # uh will this ever get executed now that i put in that return?
279
- raise "Not sure what to do with an identifier of length #{len}."
280
- end
296
+ radix = { 26 => 32, 23 => 58, 22 => 64}[ncname.length] or
297
+ raise ArgumentError,
298
+ "Not sure what to do with an identifier of length #{ncname.length}."
281
299
  end
282
300
 
283
- uuidver, content = match.captures
301
+ # note MATCH separates the variant
302
+ uuidver, *content = match.captures
303
+ content = content.join
284
304
 
285
- align = !!(content =~ /[A-Pa-p]$/) if align.nil?
305
+ align = !!(/[A-Pa-p]$/.match? content) if align.nil?
286
306
  uuidver = decode_version uuidver
287
307
  content = DECODE[radix].call content, align
288
308
 
@@ -303,7 +323,7 @@ module UUID::NCName
303
323
  # @param align [true, false] See ::to_ncname.
304
324
  #
305
325
  # @return [String] The Base64-encoded NCName
306
-
326
+ #
307
327
  def self.to_ncname_64 uuid, version: nil, align: true
308
328
  to_ncname uuid, version: version, align: align
309
329
  end
@@ -320,11 +340,42 @@ module UUID::NCName
320
340
  #
321
341
  # @return [String, nil] The corresponding UUID or nil if the input
322
342
  # is malformed.
323
-
343
+ #
324
344
  def self.from_ncname_64 ncname, format: :str, version: nil, align: nil
325
345
  from_ncname ncname, radix: 64, format: format
326
346
  end
327
347
 
348
+ # Shorthand for conversion to the Base58 version
349
+ #
350
+ # @param uuid [#to_s] The UUID
351
+ #
352
+ # @param version [0, 1] See ::to_ncname.
353
+ #
354
+ # @param align [true, false] See ::to_ncname.
355
+ #
356
+ # @return [String] The Base58-encoded NCName
357
+ #
358
+ def self.to_ncname_58 uuid, version: nil, align: true
359
+ to_ncname uuid, radix: 58, version: version, align: align
360
+ end
361
+
362
+ # Shorthand for conversion from the Base58 version
363
+ #
364
+ # @param ncname [#to_s] The Base58 variant of the NCName-encoded UUID
365
+ #
366
+ # @param format [:str, :hex, :b64, :bin] The format
367
+ #
368
+ # @param version [0, 1] See ::to_ncname.
369
+ #
370
+ # @param align [true, false] See ::to_ncname.
371
+ #
372
+ # @return [String, nil] The corresponding UUID or nil if the input
373
+ # is malformed.
374
+ #
375
+ def self.from_ncname_58 ncname, format: :str, version: nil, align: nil
376
+ from_ncname ncname, radix: 58, format: format
377
+ end
378
+
328
379
  # Shorthand for conversion to the Base32 version
329
380
  #
330
381
  # @param uuid [#to_s] The UUID
@@ -334,7 +385,7 @@ module UUID::NCName
334
385
  # @param align [true, false] See ::to_ncname.
335
386
  #
336
387
  # @return [String] The Base32-encoded NCName
337
-
388
+ #
338
389
  def self.to_ncname_32 uuid, version: nil, align: true
339
390
  to_ncname uuid, radix: 32, version: version, align: align
340
391
  end
@@ -351,7 +402,7 @@ module UUID::NCName
351
402
  #
352
403
  # @return [String, nil] The corresponding UUID or nil if the input
353
404
  # is malformed.
354
-
405
+ #
355
406
  def self.from_ncname_32 ncname, format: :str, version: nil, align: nil
356
407
  from_ncname ncname, radix: 32, format: format
357
408
  end
@@ -360,10 +411,10 @@ module UUID::NCName
360
411
  # version. This method can positively identify a token as a UUID
361
412
  # NCName, but there is a small subset of UUIDs which will produce
362
413
  # tokens which are valid in both versions. The method returns
363
- # +false+ if the token is invalid, otherwise it returns +0+ or +1+
414
+ # `false` if the token is invalid, otherwise it returns `0` or `1`
364
415
  # for the guessed version.
365
416
  #
366
- # @note Version 1 tokens always end with +I+, +J+, +K+, or +L+ (with
417
+ # @note Version 1 tokens always end with `I`, `J`, `K`, or `L` (with
367
418
  # base32 being case-insensitive), so tokens that end in something
368
419
  # else will always be version 0.
369
420
  #
@@ -372,9 +423,10 @@ module UUID::NCName
372
423
  # @param strict [false, true]
373
424
  #
374
425
  # @return [false, 0, 1]
426
+ #
375
427
  def self.valid? token, strict: false
376
428
  token = token.to_s
377
- if /^[A-Pa-p](?:[0-9A-Za-z_-]{21}|[2-7A-Za-z]{25})$/.match token
429
+ if MATCH.match? token
378
430
  # false is definitely version zero but true is only maybe version 1
379
431
  version = /^(?:.{21}[I-L]|.{25}[I-Li-l])$/.match(token) ? 1 : 0
380
432
 
@@ -6,5 +6,5 @@ unless Module.const_defined? 'UUID'
6
6
  end
7
7
 
8
8
  module UUID::NCName
9
- VERSION = "0.2.6"
9
+ VERSION = "0.3.0"
10
10
  end
@@ -32,6 +32,7 @@ DESC
32
32
  # surprisingly do not need this
33
33
  # spec.add_runtime_dependency 'uuidtools', '~> 2.1.5'
34
34
  spec.add_runtime_dependency 'base32', '~> 0.3.2'
35
+ spec.add_runtime_dependency 'base58', '~> 0.2.3'
35
36
 
36
37
  spec.add_development_dependency 'bundler', '~> 2.1'
37
38
  spec.add_development_dependency 'rake', '~> 13.0'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: uuid-ncname
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dorian Taylor
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-07-28 00:00:00.000000000 Z
11
+ date: 2021-01-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: base32
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.3.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: base58
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.2.3
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.2.3
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -81,6 +95,7 @@ files:
81
95
  - ".gitignore"
82
96
  - ".rspec"
83
97
  - ".travis.yml"
98
+ - ".yardopts"
84
99
  - Gemfile
85
100
  - LICENSE
86
101
  - README.md
@@ -95,7 +110,7 @@ homepage: https://github.com/doriantaylor/rb-uuid-ncname
95
110
  licenses:
96
111
  - Apache-2.0
97
112
  metadata: {}
98
- post_install_message:
113
+ post_install_message:
99
114
  rdoc_options: []
100
115
  require_paths:
101
116
  - lib
@@ -110,8 +125,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
110
125
  - !ruby/object:Gem::Version
111
126
  version: '0'
112
127
  requirements: []
113
- rubygems_version: 3.1.2
114
- signing_key:
128
+ rubygems_version: 3.1.4
129
+ signing_key:
115
130
  specification_version: 4
116
131
  summary: Format a UUID as a valid NCName.
117
132
  test_files: []