Skip to content

Commit 946550b

Browse files
authored
Merge pull request rails#49067 from p8/performance/securerandom-choose
Use SecureRandom.alphanumeric for SecureRandom.base36/base58
2 parents 7459392 + 9aeffae commit 946550b

File tree

2 files changed

+46
-12
lines changed

2 files changed

+46
-12
lines changed

activesupport/lib/active_support/core_ext/securerandom.rb

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,18 @@ module SecureRandom
1616
#
1717
# p SecureRandom.base58 # => "4kUgL2pdQMSCQtjE"
1818
# p SecureRandom.base58(24) # => "77TMHrHJFvFDwodq8w7Ev2m7"
19-
def self.base58(n = 16)
20-
SecureRandom.random_bytes(n).unpack("C*").map do |byte|
21-
idx = byte % 64
22-
idx = SecureRandom.random_number(58) if idx >= 58
23-
BASE58_ALPHABET[idx]
24-
end.join
19+
if RUBY_VERSION >= "3.3"
20+
def self.base58(n = 16)
21+
SecureRandom.alphanumeric(n, chars: BASE58_ALPHABET)
22+
end
23+
else
24+
def self.base58(n = 16)
25+
SecureRandom.random_bytes(n).unpack("C*").map do |byte|
26+
idx = byte % 64
27+
idx = SecureRandom.random_number(58) if idx >= 58
28+
BASE58_ALPHABET[idx]
29+
end.join
30+
end
2531
end
2632

2733
# SecureRandom.base36 generates a random base36 string in lowercase.
@@ -35,11 +41,17 @@ def self.base58(n = 16)
3541
#
3642
# p SecureRandom.base36 # => "4kugl2pdqmscqtje"
3743
# p SecureRandom.base36(24) # => "77tmhrhjfvfdwodq8w7ev2m7"
38-
def self.base36(n = 16)
39-
SecureRandom.random_bytes(n).unpack("C*").map do |byte|
40-
idx = byte % 64
41-
idx = SecureRandom.random_number(36) if idx >= 36
42-
BASE36_ALPHABET[idx]
43-
end.join
44+
if RUBY_VERSION >= "3.3"
45+
def self.base36(n = 16)
46+
SecureRandom.alphanumeric(n, chars: BASE36_ALPHABET)
47+
end
48+
else
49+
def self.base36(n = 16)
50+
SecureRandom.random_bytes(n).unpack("C*").map do |byte|
51+
idx = byte % 64
52+
idx = SecureRandom.random_number(36) if idx >= 36
53+
BASE36_ALPHABET[idx]
54+
end.join
55+
end
4456
end
4557
end

activesupport/test/core_ext/secure_random_test.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,18 @@ def test_base58_with_length
2828
assert_match(/^[^0OIl]+$/, s2)
2929
end
3030

31+
def test_base58_with_nil
32+
s1 = SecureRandom.base58(nil)
33+
s2 = SecureRandom.base58(nil)
34+
35+
assert_not_equal s1, s2
36+
assert_equal 16, s1.length
37+
assert_match(/^[a-zA-Z0-9]+$/, s1)
38+
assert_match(/^[a-zA-Z0-9]+$/, s2)
39+
assert_match(/^[^0OIl]+$/, s1)
40+
assert_match(/^[^0OIl]+$/, s2)
41+
end
42+
3143
def test_base36
3244
s1 = SecureRandom.base36
3345
s2 = SecureRandom.base36
@@ -47,4 +59,14 @@ def test_base36_with_length
4759
assert_match(/^[a-z0-9]+$/, s1)
4860
assert_match(/^[a-z0-9]+$/, s2)
4961
end
62+
63+
def test_base36_with_nil
64+
s1 = SecureRandom.base36(nil)
65+
s2 = SecureRandom.base36(nil)
66+
67+
assert_not_equal s1, s2
68+
assert_equal 16, s1.length
69+
assert_match(/^[a-z0-9]+$/, s1)
70+
assert_match(/^[a-z0-9]+$/, s2)
71+
end
5072
end

0 commit comments

Comments
 (0)