Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

randstring: allow specifying chars to pick from #22222

Merged
merged 13 commits into from
Jul 4, 2017
18 changes: 0 additions & 18 deletions base/docs/helpdb/Base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -766,24 +766,6 @@ julia> a
"""
select!

"""
randstring([rng,] len=8)

Create a random ASCII string of length `len`, consisting of upper- and
lower-case letters and the digits 0-9. The optional `rng` argument
specifies a random number generator, see [Random Numbers](@ref).

# Example

```jldoctest
julia> rng = MersenneTwister(1234);

julia> randstring(rng, 4)
"mbDd"
```
"""
randstring

"""
Float64(x [, mode::RoundingMode])

Expand Down
37 changes: 32 additions & 5 deletions base/random.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1618,15 +1618,42 @@ end
Base.show(io::IO, u::UUID) = write(io, Base.repr(u))

# return a random string (often useful for temporary filenames/dirnames)

"""
randstring([rng=GLOBAL_RNG], [chars], [len=8])

Create a random string of length `len`, consisting of characters from
`chars`, which defaults to the set of upper- and lower-case letters
and the digits 0-9. The optional `rng` argument specifies a random
number generator, see [Random Numbers](@ref).

# Examples
```jldoctest
julia> srand(0); randstring()
"c03rgKi1"

julia> randstring(MersenneTwister(0), 'a':'z', 6)
"wijzek"

julia> randstring("ACGT")
"TATCGGTC"
```

!!! note
`chars` can be any collection of characters, of type `Char` or
`UInt8` (more efficient), provided [`rand`](@ref) can randomly
pick characters from it.
"""
function randstring end

let b = UInt8['0':'9';'A':'Z';'a':'z']
global randstring
randstring(r::AbstractRNG, n::Int) = String(b[rand(r, 1:length(b), n)])
randstring(r::AbstractRNG) = randstring(r,8)
randstring(n::Int) = randstring(GLOBAL_RNG, n)
randstring() = randstring(GLOBAL_RNG)
randstring(r::AbstractRNG, chars=b, n::Integer=8) = String(rand(r, chars, n))
randstring(r::AbstractRNG, n::Integer) = randstring(r, b, n)
randstring(chars=b, n::Integer=8) = randstring(GLOBAL_RNG, chars, n)
randstring(n::Integer) = randstring(GLOBAL_RNG, b, n)
end


# Fill S (resized as needed) with a random subsequence of A, where
# each element of A is included in S with independent probability p.
# (Note that this is different from the problem of finding a random
Expand Down
20 changes: 20 additions & 0 deletions test/random.jl
Original file line number Diff line number Diff line change
Expand Up @@ -543,3 +543,23 @@ let r = MersenneTwister(0)
@inferred Base.Random.reserve_1(r)
@inferred Base.Random.reserve(r, 1)
end

# test randstring API
let b = ['0':'9';'A':'Z';'a':'z']
for rng = [[], [MersenneTwister(0)]]
@test length(randstring(rng...)) == 8
@test length(randstring(rng..., 20)) == 20
@test issubset(randstring(rng...), b)
for c = ['a':'z', "qwèrtï", Set(Vector{UInt8}("gcat"))],
len = [8, 20]
s = len == 8 ? randstring(rng..., c) : randstring(rng..., c, len)
@test length(s) == len
if eltype(c) == Char
@test issubset(s, c)
else # UInt8
@test issubset(s, map(Char, c))
end
end
end
@test randstring(MersenneTwister(0)) == randstring(MersenneTwister(0), b)
end