pcg_random 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/Rakefile +1 -5
- data/benchmarks/new_seed_bench.rb +39 -0
- data/benchmarks/raw_seed_bench.rb +40 -0
- data/ext/pcg_random/entropy.c +8 -4
- data/ext/pcg_random/pcg_seed.c +46 -40
- data/lib/pcg_random/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e9d916ffcf05c6305989a4a440ad40a7b3b6143e
|
4
|
+
data.tar.gz: 8db0e0f2fb5feee3390d0503c56f60ad0c33ce22
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8074251b1e55a97ede7e8d34e815067f5032908c809d6cf26c578a9c55abb4974bf1d071796396d4ef430cd02802c89763d1dd289a9dbe6945bcc373decb2672
|
7
|
+
data.tar.gz: 8a0d123279a6973c28b4a10f33f42f58deac929fa37d1931067e20c34cd7b2b510ad16755d3b2cf3a8ebad8e0bc8c638de1aa83eb9f4529268c113e37db951e4
|
data/.gitignore
CHANGED
data/Rakefile
CHANGED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
require 'pcg_random'
|
3
|
+
|
4
|
+
|
5
|
+
# Benchmark of Random.new_seed vs PCGRandom.new_seed
|
6
|
+
# ==================================================
|
7
|
+
#
|
8
|
+
# Benchmark created around: 2016-03-20 14:28:07 +0000
|
9
|
+
#
|
10
|
+
# Running for: 100000 iterations
|
11
|
+
#
|
12
|
+
# Rehearsal ------------------------------------------------------
|
13
|
+
# Random.new_seed 0.110000 1.030000 1.140000 ( 1.135205)
|
14
|
+
# PCGRandom.new_seed 0.090000 1.060000 1.150000 ( 1.157619)
|
15
|
+
# --------------------------------------------- total: 2.290000sec
|
16
|
+
#
|
17
|
+
# user system total real
|
18
|
+
# Random.new_seed 0.090000 1.250000 1.340000 ( 1.348947)
|
19
|
+
# PCGRandom.new_seed 0.150000 1.000000 1.150000 ( 1.146167)
|
20
|
+
|
21
|
+
|
22
|
+
Iterations = 100_000
|
23
|
+
|
24
|
+
puts "Benchmark of Random.new_seed vs PCGRandom.new_seed"
|
25
|
+
puts "=================================================="
|
26
|
+
puts ""
|
27
|
+
puts "Benchmark created around: #{Time.now}"
|
28
|
+
puts ""
|
29
|
+
puts "Running for: #{Iterations} iterations"
|
30
|
+
puts ""
|
31
|
+
Benchmark.bmbm do |bench|
|
32
|
+
bench.report("Random.new_seed") do
|
33
|
+
Iterations.times {Random.new_seed}
|
34
|
+
end
|
35
|
+
|
36
|
+
bench.report("PCGRandom.new_seed") do
|
37
|
+
Iterations.times {PCGRandom.new_seed}
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
require 'pcg_random'
|
3
|
+
|
4
|
+
|
5
|
+
# Benchmark of Random.raw_seed(16) vs PCGRandom.raw_seed(16)
|
6
|
+
# ==================================================
|
7
|
+
#
|
8
|
+
# Benchmark created around: 2016-03-20 14:34:40 +0000
|
9
|
+
#
|
10
|
+
# Running for: 100000 iterations
|
11
|
+
#
|
12
|
+
# Rehearsal ----------------------------------------------------------
|
13
|
+
# Random.raw_seed(16) 0.060000 1.110000 1.170000 ( 1.173924)
|
14
|
+
# PCGRandom.raw_seed(16) 0.060000 1.110000 1.170000 ( 1.175782)
|
15
|
+
# ------------------------------------------------- total: 2.340000sec
|
16
|
+
#
|
17
|
+
# user system total real
|
18
|
+
# Random.raw_seed(16) 0.060000 1.230000 1.290000 ( 1.292141)
|
19
|
+
# PCGRandom.raw_seed(16) 0.080000 1.100000 1.180000 ( 1.189046)
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
Iterations = 100_000
|
24
|
+
SeedSize = 16
|
25
|
+
puts "Benchmark of Random.raw_seed(#{SeedSize}) vs PCGRandom.raw_seed(#{SeedSize})"
|
26
|
+
puts "=================================================="
|
27
|
+
puts ""
|
28
|
+
puts "Benchmark created around: #{Time.now}"
|
29
|
+
puts ""
|
30
|
+
puts "Running for: #{Iterations} iterations"
|
31
|
+
puts ""
|
32
|
+
Benchmark.bmbm do |bench|
|
33
|
+
bench.report("Random.raw_seed(#{SeedSize})") do
|
34
|
+
Iterations.times {Random.raw_seed SeedSize}
|
35
|
+
end
|
36
|
+
|
37
|
+
bench.report("PCGRandom.raw_seed(#{SeedSize})") do
|
38
|
+
Iterations.times {PCGRandom.raw_seed SeedSize}
|
39
|
+
end
|
40
|
+
end
|
data/ext/pcg_random/entropy.c
CHANGED
@@ -61,17 +61,21 @@
|
|
61
61
|
|
62
62
|
#if HAVE_DEV_RANDOM
|
63
63
|
/* entropy_getbytes(dest, size):
|
64
|
-
* Use /dev/
|
64
|
+
* Use /dev/urandom to get some external entropy for seeding purposes.
|
65
65
|
*
|
66
66
|
* Note:
|
67
|
-
* If reading /dev/
|
67
|
+
* If reading /dev/urandom fails (which ought to never happen), it returns
|
68
68
|
* false, otherwise it returns true. If it fails, you could instead call
|
69
69
|
* fallback_entropy_getbytes which always succeeds.
|
70
|
+
* Note2:
|
71
|
+
* This version is an edited copy of the original entropy.c used in pcg-c
|
72
|
+
* It uses /dev/urandom instead of /dev/random
|
73
|
+
* (Read: http://www.2uo.de/myths-about-urandom/)
|
70
74
|
*/
|
71
75
|
|
72
76
|
bool entropy_getbytes(void* dest, size_t size)
|
73
77
|
{
|
74
|
-
int fd = open("/dev/
|
78
|
+
int fd = open("/dev/urandom", O_RDONLY);
|
75
79
|
if (fd < 0)
|
76
80
|
return false;
|
77
81
|
int sz = read(fd, dest, size);
|
@@ -88,7 +92,7 @@ bool entropy_getbytes(void* dest, size_t size)
|
|
88
92
|
#endif
|
89
93
|
|
90
94
|
/* fallback_entropy_getbytes(dest, size):
|
91
|
-
* Works like the /dev/
|
95
|
+
* Works like the /dev/urandom version above, but avoids using /dev/random.
|
92
96
|
* Instead, it uses a private RNG (so that repeated calls will return
|
93
97
|
* different seeds). Makes no attempt at cryptographic security.
|
94
98
|
*/
|
data/ext/pcg_random/pcg_seed.c
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#include <ruby.h>
|
2
2
|
#include <pcg_variants.h>
|
3
3
|
#include <stdbool.h>
|
4
|
+
#include <stdint.h>
|
4
5
|
|
5
6
|
#include "entropy.h"
|
6
7
|
#include "rb_constants.h"
|
@@ -8,15 +9,14 @@
|
|
8
9
|
|
9
10
|
static VALUE pcg_new_seed_bytestr(unsigned long seed_size);
|
10
11
|
static VALUE pcg_raw_seed_bytestr(size_t size);
|
11
|
-
static VALUE pcg_rb_unpack_str_uint(VALUE str);
|
12
12
|
|
13
13
|
/*
|
14
|
-
* Returns a n-
|
14
|
+
* Returns a n-byte integer that stores the seed value used to seed the
|
15
15
|
* initial state and sequence for the PCG generator.
|
16
16
|
* If no parameters are supplied it default to a 128-bit seed size
|
17
17
|
*
|
18
18
|
* @param size Number of bytes (EVEN!) that the generated seed must contain.
|
19
|
-
* Defaults to 16 Bytes = 128 bits
|
19
|
+
* Defaults to 16 Bytes (uint8_t) = 128 bits
|
20
20
|
*
|
21
21
|
* @raise ArgumentError if size is not even
|
22
22
|
*/
|
@@ -28,7 +28,7 @@ pcg_func_new_seed(int argc, VALUE *argv, VALUE self)
|
|
28
28
|
|
29
29
|
if(argc == 0)
|
30
30
|
{
|
31
|
-
return pcg_new_seed_bytestr(
|
31
|
+
return pcg_new_seed_bytestr(16 * sizeof(uint8_t));
|
32
32
|
}
|
33
33
|
|
34
34
|
rb_scan_args(argc, argv, "01", &seed_size);
|
@@ -40,7 +40,7 @@ pcg_func_new_seed(int argc, VALUE *argv, VALUE self)
|
|
40
40
|
{
|
41
41
|
rb_raise(rb_eArgError, "Seed size must be even! Found %lu", n);
|
42
42
|
}
|
43
|
-
return pcg_new_seed_bytestr(n * sizeof(
|
43
|
+
return pcg_new_seed_bytestr(n * sizeof(uint8_t));
|
44
44
|
}
|
45
45
|
|
46
46
|
/*
|
@@ -67,37 +67,12 @@ bool
|
|
67
67
|
pcg_func_entropy_getbytes(void *dest, size_t size)
|
68
68
|
{
|
69
69
|
// Get random bytes from /dev/random or a fallback source
|
70
|
-
|
71
|
-
}
|
72
|
-
|
73
|
-
/*
|
74
|
-
* Internal - Unpacks a string `str` wuth String#unpack
|
75
|
-
*/
|
76
|
-
static VALUE
|
77
|
-
pcg_rb_unpack_str_uint(VALUE str)
|
78
|
-
{
|
79
|
-
VALUE ary, result, current, base;
|
80
|
-
unsigned long len;
|
81
|
-
|
82
|
-
// This would be an array of 8 bit fixnums, effectively representing it in
|
83
|
-
// base-256
|
84
|
-
ary = rb_funcall(str, rb_intern("unpack"), 1, rb_str_new2("C*\0"));
|
85
|
-
len = RARRAY_LEN(ary);
|
86
|
-
|
87
|
-
base = INT2FIX(256);
|
88
|
-
result = pcg_rb_zero;
|
89
|
-
|
90
|
-
// First entry in array corresponds to highest significance
|
91
|
-
for(int i = 0; i < len; ++i)
|
70
|
+
if(!entropy_getbytes(dest, size))
|
92
71
|
{
|
93
|
-
|
94
|
-
|
95
|
-
// Currently this doesnt utilize the C-API a effectively
|
96
|
-
result = rb_funcall(result, pcg_rb_plus, 1, current);
|
97
|
-
result = rb_funcall(result, pcg_rb_mul, 1 , base);
|
72
|
+
fallback_entropy_getbytes(dest, size);
|
73
|
+
return true;
|
98
74
|
}
|
99
|
-
|
100
|
-
return result;
|
75
|
+
return true;
|
101
76
|
}
|
102
77
|
|
103
78
|
/*
|
@@ -107,9 +82,13 @@ pcg_rb_unpack_str_uint(VALUE str)
|
|
107
82
|
static VALUE
|
108
83
|
pcg_raw_seed_bytestr(size_t size)
|
109
84
|
{
|
110
|
-
char *bytestr = (char *) malloc(size + 1);
|
111
85
|
VALUE result;
|
112
|
-
|
86
|
+
char *bytestr = (char *) malloc(size + 1);
|
87
|
+
if(bytestr == NULL)
|
88
|
+
{
|
89
|
+
rb_raise(rb_eNoMemError,
|
90
|
+
"Could not malloc enough space for %lu-byte seed!", size);
|
91
|
+
}
|
113
92
|
memset(bytestr, 0, size + 1);
|
114
93
|
pcg_func_entropy_getbytes((void *)bytestr, size);
|
115
94
|
|
@@ -127,8 +106,35 @@ pcg_raw_seed_bytestr(size_t size)
|
|
127
106
|
static VALUE
|
128
107
|
pcg_new_seed_bytestr(unsigned long seed_size)
|
129
108
|
{
|
130
|
-
VALUE
|
131
|
-
|
132
|
-
|
109
|
+
VALUE result;
|
110
|
+
uint8_t *bytes = (uint8_t *) malloc(seed_size * sizeof(uint8_t));
|
111
|
+
unsigned long *buf = (unsigned long *) malloc(seed_size * sizeof(unsigned long));
|
112
|
+
|
113
|
+
if(bytes == NULL || buf == NULL)
|
114
|
+
{
|
115
|
+
rb_raise(rb_eNoMemError, "Could not malloc enough memory!");
|
116
|
+
}
|
117
|
+
|
118
|
+
memset(bytes, 0, seed_size);
|
119
|
+
|
120
|
+
if(!pcg_func_entropy_getbytes((void *)bytes, seed_size))
|
121
|
+
{
|
122
|
+
rb_raise(rb_eRuntimeError, "Unable to generate seed!");
|
123
|
+
}
|
124
|
+
|
125
|
+
// Populate an array of longs to feed to rb_big_unpack()
|
126
|
+
for(int i = 0; i < seed_size; ++i)
|
127
|
+
{
|
128
|
+
buf[i] = (unsigned long) bytes[i];
|
129
|
+
}
|
130
|
+
|
131
|
+
// Inspired from ruby's very own random.c
|
132
|
+
// see: http://rxr.whitequark.org/mri/source/random.c#493
|
133
|
+
// Also: http://rxr.whitequark.org/mri/source/random.c#443
|
134
|
+
result = rb_big_unpack(buf, seed_size);
|
135
|
+
|
136
|
+
free(bytes);
|
137
|
+
free(buf);
|
138
|
+
|
139
|
+
return result;
|
133
140
|
}
|
134
|
-
|
data/lib/pcg_random/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pcg_random
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vaibhav Yenamandra
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-03-
|
11
|
+
date: 2016-03-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -96,6 +96,8 @@ files:
|
|
96
96
|
- LICENSE.txt
|
97
97
|
- README.md
|
98
98
|
- Rakefile
|
99
|
+
- benchmarks/new_seed_bench.rb
|
100
|
+
- benchmarks/raw_seed_bench.rb
|
99
101
|
- bin/console
|
100
102
|
- bin/setup
|
101
103
|
- ext/pcg_random/entropy.c
|