pcg_random 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|