securerandom 0.1.1 → 0.2.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: 7c86f5641616ad68142ce8d77c366c677f495279fffc3e73f3755c40e4afb4b1
4
- data.tar.gz: 8799229ff9e615d0a231c55fe44942412ea6a78280a3b2901f80b96d31d9aee6
3
+ metadata.gz: 6852f43d47cdb9a38bd51e8981b8db11542785bdcc9cb12d99cff489ac09a75c
4
+ data.tar.gz: ad104da5f10efc9897ec75e0ea0b84867fdb23c599fe42b914e6b8b68fe35471
5
5
  SHA512:
6
- metadata.gz: 6be30a699631025d67240f44ea769b61a3b85b2d776113a4da72fb7e3dd0a73f0c7ec1cbbe952bfdcdacbf0492c57639e64fdf595d896831b628dee4c890d0b5
7
- data.tar.gz: cc815744e7d944bfe3b1764cfba6ad1cbe52a8e4bae0ef09803609042ea972b7d22c0eaac6918c9ab52c38293df0030f3a1e8d4d143e10855809415a25964fd8
6
+ metadata.gz: '09ffdc8afb40305864b664da22060adfeb63a544a4066f38bbb61641694970da98d260359e3ac1ce88a339637281e8518f5955d819ef5cb2ca675a63d5311b5d'
7
+ data.tar.gz: 77991f3b46bcdf3da8c6637f695c72de4a270834c91ad8e1bfc44b61629d324b651051ff059e7c01c02b327459dbb1190afb17d6337f5ea1bd2260581f5f8bf9
@@ -7,8 +7,8 @@ jobs:
7
7
  name: build (${{ matrix.ruby }} / ${{ matrix.os }})
8
8
  strategy:
9
9
  matrix:
10
- ruby: [ 2.7, 2.6, 2.5, head ]
11
- os: [ ubuntu-latest, macos-latest ]
10
+ ruby: [ head, '3.0', '2.7', '2.6' ]
11
+ os: [ ubuntu-latest, macos-latest, windows-latest ]
12
12
  runs-on: ${{ matrix.os }}
13
13
  steps:
14
14
  - uses: actions/checkout@v2
@@ -0,0 +1,217 @@
1
+ # -*- coding: us-ascii -*-
2
+ # frozen_string_literal: true
3
+
4
+ # == Random number formatter.
5
+ #
6
+ # Formats generated random numbers in many manners.
7
+ #
8
+ # === Examples
9
+ #
10
+ # Generate random hexadecimal strings:
11
+ #
12
+ # require 'random/formatter'
13
+ #
14
+ # prng.hex(10) #=> "52750b30ffbc7de3b362"
15
+ # prng.hex(10) #=> "92b15d6c8dc4beb5f559"
16
+ # prng.hex(13) #=> "39b290146bea6ce975c37cfc23"
17
+ #
18
+ # Generate random base64 strings:
19
+ #
20
+ # prng.base64(10) #=> "EcmTPZwWRAozdA=="
21
+ # prng.base64(10) #=> "KO1nIU+p9DKxGg=="
22
+ # prng.base64(12) #=> "7kJSM/MzBJI+75j8"
23
+ #
24
+ # Generate random binary strings:
25
+ #
26
+ # prng.random_bytes(10) #=> "\016\t{\370g\310pbr\301"
27
+ # prng.random_bytes(10) #=> "\323U\030TO\234\357\020\a\337"
28
+ #
29
+ # Generate alphanumeric strings:
30
+ #
31
+ # prng.alphanumeric(10) #=> "S8baxMJnPl"
32
+ # prng.alphanumeric(10) #=> "aOxAg8BAJe"
33
+ #
34
+ # Generate UUIDs:
35
+ #
36
+ # prng.uuid #=> "2d931510-d99f-494a-8c67-87feb05e1594"
37
+ # prng.uuid #=> "bad85eb9-0713-4da7-8d36-07a8e4b00eab"
38
+
39
+ module Random::Formatter
40
+
41
+ # Random::Formatter#random_bytes generates a random binary string.
42
+ #
43
+ # The argument _n_ specifies the length of the result string.
44
+ #
45
+ # If _n_ is not specified or is nil, 16 is assumed.
46
+ # It may be larger in future.
47
+ #
48
+ # The result may contain any byte: "\x00" - "\xff".
49
+ #
50
+ # require 'random/formatter'
51
+ #
52
+ # prng.random_bytes #=> "\xD8\\\xE0\xF4\r\xB2\xFC*WM\xFF\x83\x18\xF45\xB6"
53
+ # prng.random_bytes #=> "m\xDC\xFC/\a\x00Uf\xB2\xB2P\xBD\xFF6S\x97"
54
+ def random_bytes(n=nil)
55
+ n = n ? n.to_int : 16
56
+ gen_random(n)
57
+ end
58
+
59
+ # Random::Formatter#hex generates a random hexadecimal string.
60
+ #
61
+ # The argument _n_ specifies the length, in bytes, of the random number to be generated.
62
+ # The length of the resulting hexadecimal string is twice of _n_.
63
+ #
64
+ # If _n_ is not specified or is nil, 16 is assumed.
65
+ # It may be larger in the future.
66
+ #
67
+ # The result may contain 0-9 and a-f.
68
+ #
69
+ # require 'random/formatter'
70
+ #
71
+ # prng.hex #=> "eb693ec8252cd630102fd0d0fb7c3485"
72
+ # prng.hex #=> "91dc3bfb4de5b11d029d376634589b61"
73
+ def hex(n=nil)
74
+ random_bytes(n).unpack1("H*")
75
+ end
76
+
77
+ # Random::Formatter#base64 generates a random base64 string.
78
+ #
79
+ # The argument _n_ specifies the length, in bytes, of the random number
80
+ # to be generated. The length of the result string is about 4/3 of _n_.
81
+ #
82
+ # If _n_ is not specified or is nil, 16 is assumed.
83
+ # It may be larger in the future.
84
+ #
85
+ # The result may contain A-Z, a-z, 0-9, "+", "/" and "=".
86
+ #
87
+ # require 'random/formatter'
88
+ #
89
+ # prng.base64 #=> "/2BuBuLf3+WfSKyQbRcc/A=="
90
+ # prng.base64 #=> "6BbW0pxO0YENxn38HMUbcQ=="
91
+ #
92
+ # See RFC 3548 for the definition of base64.
93
+ def base64(n=nil)
94
+ [random_bytes(n)].pack("m0")
95
+ end
96
+
97
+ # Random::Formatter#urlsafe_base64 generates a random URL-safe base64 string.
98
+ #
99
+ # The argument _n_ specifies the length, in bytes, of the random number
100
+ # to be generated. The length of the result string is about 4/3 of _n_.
101
+ #
102
+ # If _n_ is not specified or is nil, 16 is assumed.
103
+ # It may be larger in the future.
104
+ #
105
+ # The boolean argument _padding_ specifies the padding.
106
+ # If it is false or nil, padding is not generated.
107
+ # Otherwise padding is generated.
108
+ # By default, padding is not generated because "=" may be used as a URL delimiter.
109
+ #
110
+ # The result may contain A-Z, a-z, 0-9, "-" and "_".
111
+ # "=" is also used if _padding_ is true.
112
+ #
113
+ # require 'random/formatter'
114
+ #
115
+ # prng.urlsafe_base64 #=> "b4GOKm4pOYU_-BOXcrUGDg"
116
+ # prng.urlsafe_base64 #=> "UZLdOkzop70Ddx-IJR0ABg"
117
+ #
118
+ # prng.urlsafe_base64(nil, true) #=> "i0XQ-7gglIsHGV2_BNPrdQ=="
119
+ # prng.urlsafe_base64(nil, true) #=> "-M8rLhr7JEpJlqFGUMmOxg=="
120
+ #
121
+ # See RFC 3548 for the definition of URL-safe base64.
122
+ def urlsafe_base64(n=nil, padding=false)
123
+ s = [random_bytes(n)].pack("m0")
124
+ s.tr!("+/", "-_")
125
+ s.delete!("=") unless padding
126
+ s
127
+ end
128
+
129
+ # Random::Formatter#uuid generates a random v4 UUID (Universally Unique IDentifier).
130
+ #
131
+ # require 'random/formatter'
132
+ #
133
+ # prng.uuid #=> "2d931510-d99f-494a-8c67-87feb05e1594"
134
+ # prng.uuid #=> "bad85eb9-0713-4da7-8d36-07a8e4b00eab"
135
+ # prng.uuid #=> "62936e70-1815-439b-bf89-8492855a7e6b"
136
+ #
137
+ # The version 4 UUID is purely random (except the version).
138
+ # It doesn't contain meaningful information such as MAC addresses, timestamps, etc.
139
+ #
140
+ # The result contains 122 random bits (15.25 random bytes).
141
+ #
142
+ # See RFC 4122 for details of UUID.
143
+ #
144
+ def uuid
145
+ ary = random_bytes(16).unpack("NnnnnN")
146
+ ary[2] = (ary[2] & 0x0fff) | 0x4000
147
+ ary[3] = (ary[3] & 0x3fff) | 0x8000
148
+ "%08x-%04x-%04x-%04x-%04x%08x" % ary
149
+ end
150
+
151
+ private def gen_random(n)
152
+ self.bytes(n)
153
+ end
154
+
155
+ # Random::Formatter#choose generates a string that randomly draws from a
156
+ # source array of characters.
157
+ #
158
+ # The argument _source_ specifies the array of characters from which
159
+ # to generate the string.
160
+ # The argument _n_ specifies the length, in characters, of the string to be
161
+ # generated.
162
+ #
163
+ # The result may contain whatever characters are in the source array.
164
+ #
165
+ # require 'random/formatter'
166
+ #
167
+ # prng.choose([*'l'..'r'], 16) #=> "lmrqpoonmmlqlron"
168
+ # prng.choose([*'0'..'9'], 5) #=> "27309"
169
+ private def choose(source, n)
170
+ size = source.size
171
+ m = 1
172
+ limit = size
173
+ while limit * size <= 0x100000000
174
+ limit *= size
175
+ m += 1
176
+ end
177
+ result = ''.dup
178
+ while m <= n
179
+ rs = random_number(limit)
180
+ is = rs.digits(size)
181
+ (m-is.length).times { is << 0 }
182
+ result << source.values_at(*is).join('')
183
+ n -= m
184
+ end
185
+ if 0 < n
186
+ rs = random_number(limit)
187
+ is = rs.digits(size)
188
+ if is.length < n
189
+ (n-is.length).times { is << 0 }
190
+ else
191
+ is.pop while n < is.length
192
+ end
193
+ result.concat source.values_at(*is).join('')
194
+ end
195
+ result
196
+ end
197
+
198
+ ALPHANUMERIC = [*'A'..'Z', *'a'..'z', *'0'..'9']
199
+ # Random::Formatter#alphanumeric generates a random alphanumeric string.
200
+ #
201
+ # The argument _n_ specifies the length, in characters, of the alphanumeric
202
+ # string to be generated.
203
+ #
204
+ # If _n_ is not specified or is nil, 16 is assumed.
205
+ # It may be larger in the future.
206
+ #
207
+ # The result may contain A-Z, a-z and 0-9.
208
+ #
209
+ # require 'random/formatter'
210
+ #
211
+ # prng.alphanumeric #=> "2BuBuLf3WfSKyQbR"
212
+ # prng.alphanumeric(10) #=> "i6K93NdqiH"
213
+ def alphanumeric(n=nil)
214
+ n = 16 if n.nil?
215
+ choose(ALPHANUMERIC, n)
216
+ end
217
+ end
data/lib/securerandom.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  # -*- coding: us-ascii -*-
2
2
  # frozen_string_literal: true
3
3
 
4
+ require 'random/formatter'
5
+
4
6
  # == Secure random number generator interface.
5
7
  #
6
8
  # This library is an interface to secure random number generators which are
@@ -33,37 +35,8 @@
33
35
  # These methods are usable as class methods of SecureRandom such as
34
36
  # +SecureRandom.hex+.
35
37
  #
36
- # === Examples
37
- #
38
- # Generate random hexadecimal strings:
39
- #
40
- # require 'securerandom'
41
- #
42
- # SecureRandom.hex(10) #=> "52750b30ffbc7de3b362"
43
- # SecureRandom.hex(10) #=> "92b15d6c8dc4beb5f559"
44
- # SecureRandom.hex(13) #=> "39b290146bea6ce975c37cfc23"
45
- #
46
- # Generate random base64 strings:
47
- #
48
- # SecureRandom.base64(10) #=> "EcmTPZwWRAozdA=="
49
- # SecureRandom.base64(10) #=> "KO1nIU+p9DKxGg=="
50
- # SecureRandom.base64(12) #=> "7kJSM/MzBJI+75j8"
51
- #
52
- # Generate random binary strings:
53
- #
54
- # SecureRandom.random_bytes(10) #=> "\016\t{\370g\310pbr\301"
55
- # SecureRandom.random_bytes(10) #=> "\323U\030TO\234\357\020\a\337"
56
- #
57
- # Generate alphanumeric strings:
58
- #
59
- # SecureRandom.alphanumeric(10) #=> "S8baxMJnPl"
60
- # SecureRandom.alphanumeric(10) #=> "aOxAg8BAJe"
61
- #
62
- # Generate UUIDs:
63
- #
64
- # SecureRandom.uuid #=> "2d931510-d99f-494a-8c67-87feb05e1594"
65
- # SecureRandom.uuid #=> "bad85eb9-0713-4da7-8d36-07a8e4b00eab"
66
- #
38
+ # If a secure random number generator is not available,
39
+ # +NotImplementedError+ is raised.
67
40
 
68
41
  module SecureRandom
69
42
  class << self
@@ -116,202 +89,4 @@ module SecureRandom
116
89
  end
117
90
  end
118
91
 
119
- module Random::Formatter
120
-
121
- # SecureRandom.random_bytes generates a random binary string.
122
- #
123
- # The argument _n_ specifies the length of the result string.
124
- #
125
- # If _n_ is not specified or is nil, 16 is assumed.
126
- # It may be larger in future.
127
- #
128
- # The result may contain any byte: "\x00" - "\xff".
129
- #
130
- # require 'securerandom'
131
- #
132
- # SecureRandom.random_bytes #=> "\xD8\\\xE0\xF4\r\xB2\xFC*WM\xFF\x83\x18\xF45\xB6"
133
- # SecureRandom.random_bytes #=> "m\xDC\xFC/\a\x00Uf\xB2\xB2P\xBD\xFF6S\x97"
134
- #
135
- # If a secure random number generator is not available,
136
- # +NotImplementedError+ is raised.
137
- def random_bytes(n=nil)
138
- n = n ? n.to_int : 16
139
- gen_random(n)
140
- end
141
-
142
- # SecureRandom.hex generates a random hexadecimal string.
143
- #
144
- # The argument _n_ specifies the length, in bytes, of the random number to be generated.
145
- # The length of the resulting hexadecimal string is twice of _n_.
146
- #
147
- # If _n_ is not specified or is nil, 16 is assumed.
148
- # It may be larger in the future.
149
- #
150
- # The result may contain 0-9 and a-f.
151
- #
152
- # require 'securerandom'
153
- #
154
- # SecureRandom.hex #=> "eb693ec8252cd630102fd0d0fb7c3485"
155
- # SecureRandom.hex #=> "91dc3bfb4de5b11d029d376634589b61"
156
- #
157
- # If a secure random number generator is not available,
158
- # +NotImplementedError+ is raised.
159
- def hex(n=nil)
160
- random_bytes(n).unpack("H*")[0]
161
- end
162
-
163
- # SecureRandom.base64 generates a random base64 string.
164
- #
165
- # The argument _n_ specifies the length, in bytes, of the random number
166
- # to be generated. The length of the result string is about 4/3 of _n_.
167
- #
168
- # If _n_ is not specified or is nil, 16 is assumed.
169
- # It may be larger in the future.
170
- #
171
- # The result may contain A-Z, a-z, 0-9, "+", "/" and "=".
172
- #
173
- # require 'securerandom'
174
- #
175
- # SecureRandom.base64 #=> "/2BuBuLf3+WfSKyQbRcc/A=="
176
- # SecureRandom.base64 #=> "6BbW0pxO0YENxn38HMUbcQ=="
177
- #
178
- # If a secure random number generator is not available,
179
- # +NotImplementedError+ is raised.
180
- #
181
- # See RFC 3548 for the definition of base64.
182
- def base64(n=nil)
183
- [random_bytes(n)].pack("m0")
184
- end
185
-
186
- # SecureRandom.urlsafe_base64 generates a random URL-safe base64 string.
187
- #
188
- # The argument _n_ specifies the length, in bytes, of the random number
189
- # to be generated. The length of the result string is about 4/3 of _n_.
190
- #
191
- # If _n_ is not specified or is nil, 16 is assumed.
192
- # It may be larger in the future.
193
- #
194
- # The boolean argument _padding_ specifies the padding.
195
- # If it is false or nil, padding is not generated.
196
- # Otherwise padding is generated.
197
- # By default, padding is not generated because "=" may be used as a URL delimiter.
198
- #
199
- # The result may contain A-Z, a-z, 0-9, "-" and "_".
200
- # "=" is also used if _padding_ is true.
201
- #
202
- # require 'securerandom'
203
- #
204
- # SecureRandom.urlsafe_base64 #=> "b4GOKm4pOYU_-BOXcrUGDg"
205
- # SecureRandom.urlsafe_base64 #=> "UZLdOkzop70Ddx-IJR0ABg"
206
- #
207
- # SecureRandom.urlsafe_base64(nil, true) #=> "i0XQ-7gglIsHGV2_BNPrdQ=="
208
- # SecureRandom.urlsafe_base64(nil, true) #=> "-M8rLhr7JEpJlqFGUMmOxg=="
209
- #
210
- # If a secure random number generator is not available,
211
- # +NotImplementedError+ is raised.
212
- #
213
- # See RFC 3548 for the definition of URL-safe base64.
214
- def urlsafe_base64(n=nil, padding=false)
215
- s = [random_bytes(n)].pack("m0")
216
- s.tr!("+/", "-_")
217
- s.delete!("=") unless padding
218
- s
219
- end
220
-
221
- # SecureRandom.uuid generates a random v4 UUID (Universally Unique IDentifier).
222
- #
223
- # require 'securerandom'
224
- #
225
- # SecureRandom.uuid #=> "2d931510-d99f-494a-8c67-87feb05e1594"
226
- # SecureRandom.uuid #=> "bad85eb9-0713-4da7-8d36-07a8e4b00eab"
227
- # SecureRandom.uuid #=> "62936e70-1815-439b-bf89-8492855a7e6b"
228
- #
229
- # The version 4 UUID is purely random (except the version).
230
- # It doesn't contain meaningful information such as MAC addresses, timestamps, etc.
231
- #
232
- # The result contains 122 random bits (15.25 random bytes).
233
- #
234
- # See RFC 4122 for details of UUID.
235
- #
236
- def uuid
237
- ary = random_bytes(16).unpack("NnnnnN")
238
- ary[2] = (ary[2] & 0x0fff) | 0x4000
239
- ary[3] = (ary[3] & 0x3fff) | 0x8000
240
- "%08x-%04x-%04x-%04x-%04x%08x" % ary
241
- end
242
-
243
- private def gen_random(n)
244
- self.bytes(n)
245
- end
246
-
247
- # SecureRandom.choose generates a string that randomly draws from a
248
- # source array of characters.
249
- #
250
- # The argument _source_ specifies the array of characters from which
251
- # to generate the string.
252
- # The argument _n_ specifies the length, in characters, of the string to be
253
- # generated.
254
- #
255
- # The result may contain whatever characters are in the source array.
256
- #
257
- # require 'securerandom'
258
- #
259
- # SecureRandom.choose([*'l'..'r'], 16) #=> "lmrqpoonmmlqlron"
260
- # SecureRandom.choose([*'0'..'9'], 5) #=> "27309"
261
- #
262
- # If a secure random number generator is not available,
263
- # +NotImplementedError+ is raised.
264
- private def choose(source, n)
265
- size = source.size
266
- m = 1
267
- limit = size
268
- while limit * size <= 0x100000000
269
- limit *= size
270
- m += 1
271
- end
272
- result = ''.dup
273
- while m <= n
274
- rs = random_number(limit)
275
- is = rs.digits(size)
276
- (m-is.length).times { is << 0 }
277
- result << source.values_at(*is).join('')
278
- n -= m
279
- end
280
- if 0 < n
281
- rs = random_number(limit)
282
- is = rs.digits(size)
283
- if is.length < n
284
- (n-is.length).times { is << 0 }
285
- else
286
- is.pop while n < is.length
287
- end
288
- result.concat source.values_at(*is).join('')
289
- end
290
- result
291
- end
292
-
293
- ALPHANUMERIC = [*'A'..'Z', *'a'..'z', *'0'..'9']
294
- # SecureRandom.alphanumeric generates a random alphanumeric string.
295
- #
296
- # The argument _n_ specifies the length, in characters, of the alphanumeric
297
- # string to be generated.
298
- #
299
- # If _n_ is not specified or is nil, 16 is assumed.
300
- # It may be larger in the future.
301
- #
302
- # The result may contain A-Z, a-z and 0-9.
303
- #
304
- # require 'securerandom'
305
- #
306
- # SecureRandom.alphanumeric #=> "2BuBuLf3WfSKyQbR"
307
- # SecureRandom.alphanumeric(10) #=> "i6K93NdqiH"
308
- #
309
- # If a secure random number generator is not available,
310
- # +NotImplementedError+ is raised.
311
- def alphanumeric(n=nil)
312
- n = 16 if n.nil?
313
- choose(ALPHANUMERIC, n)
314
- end
315
- end
316
-
317
92
  SecureRandom.extend(Random::Formatter)
@@ -0,0 +1,5 @@
1
+ task "build" => "date_epoch"
2
+
3
+ task "date_epoch" do
4
+ ENV["SOURCE_DATE_EPOCH"] = IO.popen(%W[git -C #{__dir__} log -1 --format=%ct], &:read).chomp
5
+ end
data/securerandom.gemspec CHANGED
@@ -1,13 +1,13 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "securerandom"
3
- spec.version = "0.1.1"
3
+ spec.version = "0.2.0"
4
4
  spec.authors = ["Tanaka Akira"]
5
5
  spec.email = ["akr@fsij.org"]
6
6
 
7
7
  spec.summary = %q{Interface for secure random number generator.}
8
8
  spec.description = %q{Interface for secure random number generator.}
9
9
  spec.homepage = "https://github.com/ruby/securerandom"
10
- spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
10
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.6.0")
11
11
  spec.licenses = ["Ruby", "BSD-2-Clause"]
12
12
 
13
13
  spec.metadata["homepage_uri"] = spec.homepage
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: securerandom
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tanaka Akira
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-10-21 00:00:00.000000000 Z
11
+ date: 2022-02-28 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Interface for secure random number generator.
14
14
  email:
@@ -25,7 +25,9 @@ files:
25
25
  - Rakefile
26
26
  - bin/console
27
27
  - bin/setup
28
+ - lib/random/formatter.rb
28
29
  - lib/securerandom.rb
30
+ - rakelib/epoch.rake
29
31
  - securerandom.gemspec
30
32
  homepage: https://github.com/ruby/securerandom
31
33
  licenses:
@@ -42,14 +44,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
42
44
  requirements:
43
45
  - - ">="
44
46
  - !ruby/object:Gem::Version
45
- version: 2.3.0
47
+ version: 2.6.0
46
48
  required_rubygems_version: !ruby/object:Gem::Requirement
47
49
  requirements:
48
50
  - - ">="
49
51
  - !ruby/object:Gem::Version
50
52
  version: '0'
51
53
  requirements: []
52
- rubygems_version: 3.3.0.dev
54
+ rubygems_version: 3.4.0.dev
53
55
  signing_key:
54
56
  specification_version: 4
55
57
  summary: Interface for secure random number generator.