Skip to content

Commit c4f2737

Browse files
authored
randstring: allow specifying chars to pick from (#22222)
1 parent ee4c5bc commit c4f2737

File tree

3 files changed

+52
-23
lines changed

3 files changed

+52
-23
lines changed

base/docs/helpdb/Base.jl

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -766,24 +766,6 @@ julia> a
766766
"""
767767
select!
768768

769-
"""
770-
randstring([rng,] len=8)
771-
772-
Create a random ASCII string of length `len`, consisting of upper- and
773-
lower-case letters and the digits 0-9. The optional `rng` argument
774-
specifies a random number generator, see [Random Numbers](@ref).
775-
776-
# Example
777-
778-
```jldoctest
779-
julia> rng = MersenneTwister(1234);
780-
781-
julia> randstring(rng, 4)
782-
"mbDd"
783-
```
784-
"""
785-
randstring
786-
787769
"""
788770
Float64(x [, mode::RoundingMode])
789771

base/random.jl

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,15 +1618,42 @@ end
16181618
Base.show(io::IO, u::UUID) = write(io, Base.repr(u))
16191619

16201620
# return a random string (often useful for temporary filenames/dirnames)
1621+
1622+
"""
1623+
randstring([rng=GLOBAL_RNG], [chars], [len=8])
1624+
1625+
Create a random string of length `len`, consisting of characters from
1626+
`chars`, which defaults to the set of upper- and lower-case letters
1627+
and the digits 0-9. The optional `rng` argument specifies a random
1628+
number generator, see [Random Numbers](@ref).
1629+
1630+
# Examples
1631+
```jldoctest
1632+
julia> srand(0); randstring()
1633+
"c03rgKi1"
1634+
1635+
julia> randstring(MersenneTwister(0), 'a':'z', 6)
1636+
"wijzek"
1637+
1638+
julia> randstring("ACGT")
1639+
"TATCGGTC"
1640+
```
1641+
1642+
!!! note
1643+
`chars` can be any collection of characters, of type `Char` or
1644+
`UInt8` (more efficient), provided [`rand`](@ref) can randomly
1645+
pick characters from it.
1646+
"""
1647+
function randstring end
1648+
16211649
let b = UInt8['0':'9';'A':'Z';'a':'z']
16221650
global randstring
1623-
randstring(r::AbstractRNG, n::Int) = String(b[rand(r, 1:length(b), n)])
1624-
randstring(r::AbstractRNG) = randstring(r,8)
1625-
randstring(n::Int) = randstring(GLOBAL_RNG, n)
1626-
randstring() = randstring(GLOBAL_RNG)
1651+
randstring(r::AbstractRNG, chars=b, n::Integer=8) = String(rand(r, chars, n))
1652+
randstring(r::AbstractRNG, n::Integer) = randstring(r, b, n)
1653+
randstring(chars=b, n::Integer=8) = randstring(GLOBAL_RNG, chars, n)
1654+
randstring(n::Integer) = randstring(GLOBAL_RNG, b, n)
16271655
end
16281656

1629-
16301657
# Fill S (resized as needed) with a random subsequence of A, where
16311658
# each element of A is included in S with independent probability p.
16321659
# (Note that this is different from the problem of finding a random

test/random.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,3 +543,23 @@ let r = MersenneTwister(0)
543543
@inferred Base.Random.reserve_1(r)
544544
@inferred Base.Random.reserve(r, 1)
545545
end
546+
547+
# test randstring API
548+
let b = ['0':'9';'A':'Z';'a':'z']
549+
for rng = [[], [MersenneTwister(0)]]
550+
@test length(randstring(rng...)) == 8
551+
@test length(randstring(rng..., 20)) == 20
552+
@test issubset(randstring(rng...), b)
553+
for c = ['a':'z', "qwèrtï", Set(Vector{UInt8}("gcat"))],
554+
len = [8, 20]
555+
s = len == 8 ? randstring(rng..., c) : randstring(rng..., c, len)
556+
@test length(s) == len
557+
if eltype(c) == Char
558+
@test issubset(s, c)
559+
else # UInt8
560+
@test issubset(s, map(Char, c))
561+
end
562+
end
563+
end
564+
@test randstring(MersenneTwister(0)) == randstring(MersenneTwister(0), b)
565+
end

0 commit comments

Comments
 (0)