Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
seed PRNGs from System source instead of time. (#4789)
  • Loading branch information
konovod authored and RX14 committed Aug 14, 2017
1 parent ac88068 commit d638238
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 15 deletions.
17 changes: 6 additions & 11 deletions src/random.cr
Expand Up @@ -40,19 +40,14 @@ require "random/pcg32"
module Random
DEFAULT = PCG32.new

# Returns a `UInt32` read from a counter value generated by the cycle counter
# register, or the current time on ARM processors.
def self.new_seed : UInt32
{% if flag?(:arm) || flag?(:aarch64) %}
Time.now.ticks.to_u32
{% else %}
Intrinsics.read_cycle_counter.to_u32
{% end %}
# Initializes an instance with the given *seed* and *sequence*.
def self.new(seed, sequence = 0_u64)
PCG32.new(seed.to_u64, sequence)
end

# Initializes an instance with the given *seed*. (Default: `#new_seed`)
def self.new(seed = new_seed)
PCG32.new(seed)
# Initializes an instance seeded from a system source.
def self.new
PCG32.new
end

# Generates a random unsigned integer.
Expand Down
12 changes: 10 additions & 2 deletions src/random/isaac.cr
@@ -1,3 +1,5 @@
require "crystal/system/random"

# (c) Bob Jenkins, March 1996, Public Domain
# You may use this code in any way you wish, and it is free. No warrantee.
# http://burtleburtle.net/bob/rand/isaacafa.html
Expand All @@ -10,15 +12,21 @@ class Random::ISAAC
private getter bb
private getter cc

def initialize(seeds = StaticArray(UInt32, 8).new { Random.new_seed })
private def self.random_seeds
(uninitialized StaticArray(UInt32, 8)).tap do |seeds|
System::Random.random_bytes(seeds.to_slice)
end
end

def initialize(seeds = self.random_seeds)
@rsl = StaticArray(UInt32, 256).new { 0_u32 }
@mm = StaticArray(UInt32, 256).new { 0_u32 }
@counter = 0
@aa = @bb = @cc = 0_u32
init_by_array(seeds)
end

def new_seed(seeds = StaticArray(UInt32, 8).new { Random.new_seed })
def new_seed(seeds = self.random_seeds)
@aa = @bb = @cc = 0_u32
init_by_array(seeds)
end
Expand Down
14 changes: 12 additions & 2 deletions src/random/pcg32.cr
@@ -1,3 +1,5 @@
require "random/system"

# This is a Crystal conversion of basic C PCG implementation
#
# Original file notice:
Expand Down Expand Up @@ -37,14 +39,22 @@ class Random::PCG32
@state : UInt64
@inc : UInt64

def initialize(initstate = UInt64.new(Random.new_seed), initseq = 0_u64)
def self.new
new(Random::System.rand(UInt64::MIN..UInt64::MAX), Random::System.rand(UInt64::MIN..UInt64::MAX))
end

def initialize(initstate : UInt64, initseq = 0_u64)
# initialize to zeros to prevent compiler complains
@state = 0_u64
@inc = 0_u64
new_seed(initstate, initseq)
end

def new_seed(initstate = UInt64.new(Random.new_seed), initseq = 0_u64)
def new_seed
new_seed(Random::System.rand(UInt64::MIN..UInt64::MAX), Random::System.rand(UInt64::MIN..UInt64::MAX))
end

def new_seed(initstate : UInt64, initseq = 0_u64)
@state = 0_u64
@inc = (initseq << 1) | 1
next_u
Expand Down

0 comments on commit d638238

Please sign in to comment.