prime_miller_rabin 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +263 -0
- data/Rakefile +1 -0
- data/lib/prime_miller_rabin/version.rb +5 -0
- data/lib/prime_miller_rabin.rb +124 -0
- data/prime_miller_rabin.gemspec +23 -0
- metadata +82 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a088800b7a87805ac6556b7252b6e32d426bf4b0
|
4
|
+
data.tar.gz: 68f614d2830b4874ba6d01b6d8084f0ec9c5e9f7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 94a350177a2c3eac2912fb77dd331c9db6f340d4d93eb5d0f728dfd272e1cdfd7b65f28427b9e201749cf7d2bbf71fa017ca3b78c4d767fdafc068d583c0a018
|
7
|
+
data.tar.gz: 1f497645dc17fb3e1651dc99c09ee1f417c421ad56a81e9be6795688fbfdcad746cff22512a873cf0fd127ae8c9ea20427cc009594481b0d68ffc02f3d04e83b
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Frank Hall
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,263 @@
|
|
1
|
+
# PrimeMillerRabin
|
2
|
+
|
3
|
+
Test primes using the Miller-Rabin Method.
|
4
|
+
See http://en.wikipedia.org/wiki/Miller-Rabin_primality_test for more details.
|
5
|
+
For large prime numbers this is significantly faster than Ruby's default method.
|
6
|
+
|
7
|
+
## Benchmarks
|
8
|
+
|
9
|
+
The current standard Ruby Prime Generators are
|
10
|
+
[Generator23](http://www.ruby-doc.org/stdlib-2.0/libdoc/prime/rdoc/Prime/Generator23.html),
|
11
|
+
[EratosthenesSieve](http://www.ruby-doc.org/stdlib-2.0/libdoc/prime/rdoc/Prime/EratosthenesSieve.html),
|
12
|
+
and
|
13
|
+
[TrialDivision](http://www.ruby-doc.org/stdlib-2.0/libdoc/prime/rdoc/Prime/TrialDivision.html)
|
14
|
+
|
15
|
+
The following code was used to compare Miller-Rabin with the existing Ruby Prime Generators:
|
16
|
+
|
17
|
+
Prime::MillerRabin.speed_intercept
|
18
|
+
|
19
|
+
miller_rabin = Prime::MillerRabin.new
|
20
|
+
generator23 = Prime::Generator23.new
|
21
|
+
eratosthenes = Prime::EratosthenesGenerator.new
|
22
|
+
trial_division = Prime::TrialDivisionGenerator.new
|
23
|
+
|
24
|
+
generators = [miller_rabin, generator23, eratosthenes, trial_division]
|
25
|
+
generator_names = ['MillerRabin', 'Generator23', 'Eratosthenes', 'TrialDivision']
|
26
|
+
|
27
|
+
puts(("%-15s" * generator_names.size) % generator_names + " Number Tested")
|
28
|
+
primes.each_with_index do |number|
|
29
|
+
remove = []
|
30
|
+
timings = []
|
31
|
+
generators.each_with_index do |generator, j|
|
32
|
+
if generator
|
33
|
+
name = generator_names[j]
|
34
|
+
benchmark = Benchmark.measure { Prime.prime?(number, generator) }
|
35
|
+
if benchmark.total > 120
|
36
|
+
puts "Removing #{name} as it is now exceeding 2 minutes to determine primality"
|
37
|
+
remove << generator
|
38
|
+
end
|
39
|
+
timings << benchmark.total
|
40
|
+
else
|
41
|
+
timings << nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
timings.map! { |x| x ? '%-15.6f' % [x] : '%15s' % [' '] }
|
45
|
+
timings << number
|
46
|
+
puts timings.join(' ')
|
47
|
+
generators.map! { |x| remove.include?(x) ? nil : x }
|
48
|
+
end
|
49
|
+
|
50
|
+
####The results (formatted for readability):
|
51
|
+
MillerRabin Generator23 Eratosthenes TrialDivision Number Tested
|
52
|
+
0.000000 0.000000 0.000000 0.000000 2
|
53
|
+
0.000000 0.000000 0.000000 0.000000 7
|
54
|
+
0.000000 0.000000 0.000000 0.000000 67
|
55
|
+
0.000000 0.000000 0.000000 0.000000 619
|
56
|
+
0.000000 0.000000 0.000000 0.000000 6197
|
57
|
+
0.000000 0.000000 0.000000 0.000000 61813
|
58
|
+
0.000000 0.000000 0.000000 0.000000 618041
|
59
|
+
0.000000 0.000000 0.010000 0.000000 6180341
|
60
|
+
0.000000 0.000000 0.000000 0.010000 61803419
|
61
|
+
0.000000 0.000000 0.020000 0.030000 618034003
|
62
|
+
0.000000 0.010000 0.050000 0.120000 6180339923
|
63
|
+
0.000000 0.040000 0.220000 1.690000 61803398903
|
64
|
+
0.000000 0.140000 0.990000 13.080000 618033988751
|
65
|
+
0.010000 0.390000 4.110000 119.750000 6180339887543
|
66
|
+
Removing TrialDivision as it is now exceeding 2 minutes to determine primality
|
67
|
+
0.000000 1.820000 30.460000 1081.650000 61803398875019
|
68
|
+
Removing Eratosthenes as it is now exceeding 2 minutes to determine primality
|
69
|
+
0.000000 7.180000 139.250000 618033988749911
|
70
|
+
0.010000 16.990000 6180339887498971
|
71
|
+
0.000000 53.850000 61803398874989489
|
72
|
+
Removing Generator23 as it is now exceeding 2 minutes to determine primality
|
73
|
+
0.010000 170.560000 618033988749894811
|
74
|
+
|
75
|
+
MillerRabin Number Tested
|
76
|
+
0.000000 6180339887498948681
|
77
|
+
0.000000 61803398874989486159
|
78
|
+
0.000000 618033988749894877249
|
79
|
+
0.000000 6180339887498948771861
|
80
|
+
0.020000 61803398874989479329793
|
81
|
+
0.000000 618033988749894843629693
|
82
|
+
0.010000 6180339887498948973166649
|
83
|
+
0.000000 61803398874989485436698673
|
84
|
+
0.000000 618033988749894820007248007
|
85
|
+
0.020000 6180339887498948474950385857
|
86
|
+
0.000000 61803398874989473754387579003
|
87
|
+
0.000000 618033988749894825504806010893
|
88
|
+
0.010000 6180339887498947551360618332249
|
89
|
+
0.020000 61803398874989482269005624377351
|
90
|
+
0.000000 618033988749894786661259224809529
|
91
|
+
0.010000 6180339887498948010727780323950599
|
92
|
+
0.020000 61803398874989484718963821666894041
|
93
|
+
0.000000 618033988749894884083126364088041501
|
94
|
+
0.010000 6180339887498948102961500692498350149
|
95
|
+
0.020000 61803398874989478668431765490160893959
|
96
|
+
0.000000 618033988749894805573783586380189794451
|
97
|
+
0.010000 6180339887498948055737835863801897943079
|
98
|
+
0.020000 61803398874989485393081637096535678255353
|
99
|
+
0.010000 618033988749894834588003257131289987252251
|
100
|
+
0.000000 6180339887498947881652517839295296785350671
|
101
|
+
0.020000 61803398874989486244165414105234617248252037
|
102
|
+
0.010000 618033988749894783213491626788008578938568879
|
103
|
+
0.020000 6180339887498948782872866439052136911913091139
|
104
|
+
0.010000 61803398874989490364029864846980172112537321529
|
105
|
+
0.020000 618033988749894863075479441166460873230870642701
|
106
|
+
0.010000 6180339887498948306236240753237881949152685850683
|
107
|
+
0.020000 61803398874989488254659266067206448022023187726371
|
108
|
+
0.010000 618033988749894861777405226532753966098246560383039
|
109
|
+
0.020000 6180339887498948285467053319098571435030700533743709
|
110
|
+
0.010000 61803398874989477537758550051322222735078764216058197
|
111
|
+
0.030000 618033988749894860448177230747838093194439500102631463
|
112
|
+
0.000000 6180339887498948264199405386539917468569787569258103079
|
113
|
+
0.030000 61803398874989493531029795335430005513685313509163794507
|
114
|
+
0.010000 618033988749894848198012021594053408512953632558975811599
|
115
|
+
0.020000 6180339887498947959306404625379054205386139310393785319457
|
116
|
+
0.010000 61803398874989483774453770978282381091808569225505635565881
|
117
|
+
0.030000 618033988749894815443792511252200669382367419606694849675361
|
118
|
+
0.020000 6180339887498947619220040347787051296966435652506272353222859
|
119
|
+
0.010000 61803398874989487610181945125549561435952112121023814594199579
|
120
|
+
0.030000 618033988749894876101819451255495614359521121210238145941995523
|
121
|
+
0.030000 6180339887498948212955080513466361817213398943496249088445251857
|
122
|
+
0.010000 61803398874989482129550805134663618172133989434962490884452515863
|
123
|
+
0.030000 618033988749894751143429459463296107944467923968039965359763095659
|
124
|
+
0.020000 6180339887498948446795342486410828729802972178101532233394458460333
|
125
|
+
0.020000 61803398874989478481642718356729934335736646975120073823244888571933
|
126
|
+
0.030000 618033988749894856652155661655839578904883367421943720360845238075493
|
127
|
+
0.030000 6180339887498948949645441833030610378635590461796733108293232926654757
|
128
|
+
0.010000 61803398874989480301481173134972953636273741716112229370497596164931657
|
129
|
+
0.030000 618033988749894753974954423641286068895632548351228417905324051774046223
|
130
|
+
0.030000 6180339887498948520546690390581730038298422859710161695046278715245855121
|
131
|
+
0.030000 61803398874989478928365168519136536547194805389435200848107342688424034467
|
132
|
+
0.030000 618033988749894789283651685191365365471948053894352008481073426884240343509
|
133
|
+
0.030000 6180339887498948294571027916661222540210003624234170715361482714540612255771
|
134
|
+
0.030000 61803398874989487766524411943583052027986313265829514720223808493784628461601
|
135
|
+
0.030000 618033988749894800532217995004297294265682700282490226136494383363790190149697
|
136
|
+
0.030000 6180339887498948416698319280344483481399122642162528507048910242032867738649237
|
137
|
+
0.020000 61803398874989489103496864767062961278898774093676800018696699321068267432312833
|
138
|
+
0.030000 618033988749894759394604061974146240391453136348727601568097742524293606434406857
|
139
|
+
0.030000 6180339887498947804570623956855835799750586730828140653471168226341158572966019139
|
140
|
+
0.030000 61803398874989483100696239659303319497571196124462157841676261489768925936587112561
|
141
|
+
0.040000 618033988749894911886802398044952578976757222303513599328195882519406702676701872319
|
142
|
+
0.030000 6180339887498948040470157294423934003086968742249909047796181923571167782622608752829
|
143
|
+
0.040000 61803398874989482130138159641880286889558652991755453590739062278308316616857143476423
|
144
|
+
0.040000 618033988749894793694396209256547719156563080809452726102954734101536945518474539565289
|
145
|
+
0.040000 6180339887498948378655728287161559587390005993824156217900521559920108985586295718806271
|
146
|
+
0.040000 61803398874989483786557282871615595873900059938241562179005215599201089855862957188055087
|
147
|
+
0.030000 618033988749894837865572828716155958739000599382415621790052155992010898558629571880550497
|
148
|
+
0.020000 6180339887498948830968576870427947960714166184011296269736399160078562264717483249716166887
|
149
|
+
0.040000 61803398874989484691182980038148372620548380318615842282676970799517996414125332249876365411
|
150
|
+
0.030000 618033988749894890333863264375057010044603181444123867803013957610391478937847325466187268189
|
151
|
+
0.040000 6180339887498947977001918745221006711878151744937975851870262250979402473717801191356835561549
|
152
|
+
0.050000 61803398874989483475366043046328320673053037727392809823342131810292073999820700166788504093107
|
153
|
+
0.040000 618033988749894819932273008086810192513444296161875893014863280900928542947636248655004447015003
|
154
|
+
0.030000 6180339887498948673607127596915238380081197557204429497142489999473035735094626582962223475327741
|
155
|
+
0.040000 61803398874989482941796095840775292161237938807358930435474042471020354906000153058324802711846941
|
156
|
+
0.030000 618033988749894799063759517380736188495787093956106388067133564520523529500432628412868570787086393
|
157
|
+
0.040000 6180339887498948233471206702023495749890609292500927210972190526722675451480877501491721358521925753
|
158
|
+
|
159
|
+
|
160
|
+
####Larger numbers
|
161
|
+
|
162
|
+
For primes nearing a googol (10**100) it is still subsecond.
|
163
|
+
Starting at a google - 3 the following was used for benchmarking,
|
164
|
+
|
165
|
+
Benchmark.bm do |x|
|
166
|
+
(1..50).each do |z|
|
167
|
+
exponent = "#{z}00".to_i
|
168
|
+
number = 10**exponent - 3
|
169
|
+
x.report("10**#{exponent} - 3") { number.prime? }
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
####Results (formatted for readability)
|
174
|
+
|
175
|
+
user system total real
|
176
|
+
10**100 - 3 0.000000 0.000000 0.000000 ( 0.000873)
|
177
|
+
10**200 - 3 0.000000 0.000000 0.000000 ( 0.003954)
|
178
|
+
10**300 - 3 0.010000 0.000000 0.010000 ( 0.008990)
|
179
|
+
10**400 - 3 0.020000 0.000000 0.020000 ( 0.019595)
|
180
|
+
10**500 - 3 0.030000 0.000000 0.030000 ( 0.030311)
|
181
|
+
10**600 - 3 0.050000 0.000000 0.050000 ( 0.045907)
|
182
|
+
10**700 - 3 0.080000 0.010000 0.090000 ( 0.086039)
|
183
|
+
10**800 - 3 0.120000 0.000000 0.120000 ( 0.120604)
|
184
|
+
10**900 - 3 0.140000 0.000000 0.140000 ( 0.137074)
|
185
|
+
10**1000 - 3 0.190000 0.000000 0.190000 ( 0.197226)
|
186
|
+
10**1100 - 3 0.270000 0.010000 0.280000 ( 0.267312)
|
187
|
+
10**1200 - 3 0.340000 0.000000 0.340000 ( 0.344282)
|
188
|
+
10**1300 - 3 0.370000 0.000000 0.370000 ( 0.376330)
|
189
|
+
10**1400 - 3 0.520000 0.010000 0.530000 ( 0.530934)
|
190
|
+
10**1500 - 3 0.610000 0.010000 0.620000 ( 0.622023)
|
191
|
+
10**1600 - 3 0.810000 0.010000 0.820000 ( 0.817583)
|
192
|
+
10**1700 - 3 0.910000 0.010000 0.920000 ( 0.917380)
|
193
|
+
10**1800 - 3 1.050000 0.010000 1.060000 ( 1.071910)
|
194
|
+
10**1900 - 3 1.180000 0.020000 1.200000 ( 1.189116)
|
195
|
+
10**2000 - 3 1.410000 0.020000 1.430000 ( 1.438527)
|
196
|
+
10**2100 - 3 1.480000 0.020000 1.500000 ( 1.499630)
|
197
|
+
10**2200 - 3 1.820000 0.030000 1.850000 ( 1.838164)
|
198
|
+
10**2300 - 3 2.000000 0.030000 2.030000 ( 2.026655)
|
199
|
+
10**2400 - 3 1.970000 0.020000 1.990000 ( 1.997051)
|
200
|
+
10**2500 - 3 2.580000 0.040000 2.620000 ( 2.616159)
|
201
|
+
10**2600 - 3 3.060000 0.050000 3.110000 ( 3.110208)
|
202
|
+
10**2700 - 3 2.900000 0.050000 2.950000 ( 2.950306)
|
203
|
+
10**2800 - 3 2.900000 0.050000 2.950000 ( 2.945470)
|
204
|
+
10**2900 - 3 3.310000 0.050000 3.360000 ( 3.360690)
|
205
|
+
10**3000 - 3 3.700000 0.070000 3.770000 ( 3.765682)
|
206
|
+
10**3100 - 3 4.610000 0.070000 4.680000 ( 4.680919)
|
207
|
+
10**3200 - 3 5.530000 0.080000 5.610000 ( 5.615243)
|
208
|
+
10**3300 - 3 4.770000 0.090000 4.860000 ( 4.860779)
|
209
|
+
10**3400 - 3 5.190000 0.090000 5.280000 ( 5.278715)
|
210
|
+
10**3500 - 3 5.800000 0.100000 5.900000 ( 5.891275)
|
211
|
+
10**3600 - 3 6.310000 0.110000 6.420000 ( 6.417548)
|
212
|
+
10**3700 - 3 8.450000 0.070000 8.520000 ( 8.510452)
|
213
|
+
10**3800 - 3 8.830000 0.070000 8.900000 ( 8.901605)
|
214
|
+
10**3900 - 3 8.040000 0.080000 8.120000 ( 8.114340)
|
215
|
+
10**4000 - 3 10.030000 0.050000 10.080000 ( 10.087971)
|
216
|
+
10**4100 - 3 8.730000 0.060000 8.790000 ( 8.782747)
|
217
|
+
10**4200 - 3 11.550000 0.070000 11.620000 ( 11.607290)
|
218
|
+
10**4300 - 3 10.810000 0.100000 10.910000 ( 10.913006)
|
219
|
+
10**4400 - 3 12.380000 0.180000 12.560000 ( 12.552739)
|
220
|
+
10**4500 - 3 12.580000 0.180000 12.760000 ( 12.753963)
|
221
|
+
10**4600 - 3 13.130000 0.190000 13.320000 ( 13.311686)
|
222
|
+
10**4700 - 3 14.380000 0.190000 14.570000 ( 14.560988)
|
223
|
+
10**4800 - 3 13.680000 0.220000 13.900000 ( 13.895690)
|
224
|
+
10**4900 - 3 15.800000 0.220000 16.020000 ( 16.017528)
|
225
|
+
10**5000 - 3 15.290000 0.230000 15.520000 ( 15.513277)
|
226
|
+
|
227
|
+
|
228
|
+
## Installation
|
229
|
+
|
230
|
+
Add this line to your application's Gemfile:
|
231
|
+
|
232
|
+
gem 'prime_miller_rabin'
|
233
|
+
|
234
|
+
And then execute:
|
235
|
+
|
236
|
+
$ bundle
|
237
|
+
|
238
|
+
Or install it yourself as:
|
239
|
+
|
240
|
+
$ gem install prime_miller_rabin
|
241
|
+
|
242
|
+
## Usage
|
243
|
+
|
244
|
+
require 'prime_miller_rabin'
|
245
|
+
|
246
|
+
# You now have access to Prime::MillerRabin
|
247
|
+
Prime.prime?(large_number, Prime::MillerRabin.new)
|
248
|
+
|
249
|
+
# Even when using the generator, Ruby's method for #prime? is slower than having Miller Rabin determine it directly.
|
250
|
+
# Miller Rabin can intercept the Prime.prime? function and call Miller Rabin directly when its generator is used.
|
251
|
+
# To accomplish this use:
|
252
|
+
Prime::MillerRabin.speed_intercept
|
253
|
+
|
254
|
+
# To use the speed intercept and have Miller Rabin be the default prime generator in all cases use:
|
255
|
+
Prime::MillerRabin.make_default
|
256
|
+
|
257
|
+
## Contributing
|
258
|
+
|
259
|
+
1. Fork it
|
260
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
261
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
262
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
263
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'prime'
|
2
|
+
require "prime_miller_rabin/version"
|
3
|
+
|
4
|
+
class Prime::MillerRabin < Prime::PseudoPrimeGenerator
|
5
|
+
|
6
|
+
def self.speed_intercept
|
7
|
+
Prime.send(:prepend, Prime::MillerRabin::PrimeIntercept)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.make_default
|
11
|
+
Prime.send(:prepend, Prime::MillerRabin::Default::Prime, Prime::MillerRabin::PrimeIntercept)
|
12
|
+
Integer.send(:prepend, Prime::MillerRabin::Default::Integer)
|
13
|
+
end
|
14
|
+
|
15
|
+
def succ()
|
16
|
+
self.last_prime = next_prime(last_prime || 1)
|
17
|
+
end
|
18
|
+
|
19
|
+
def rewind()
|
20
|
+
self.last_prime = nil
|
21
|
+
end
|
22
|
+
|
23
|
+
def prime?(x)
|
24
|
+
miller_rabin(x)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
attr_accessor :last_prime
|
30
|
+
|
31
|
+
def likely_prime?(a, n)
|
32
|
+
d = n - 1
|
33
|
+
s = 0
|
34
|
+
while d % 2 == 0 do
|
35
|
+
d >>= 1
|
36
|
+
s += 1
|
37
|
+
end
|
38
|
+
|
39
|
+
b = 1
|
40
|
+
while d > 0
|
41
|
+
u = d % 2
|
42
|
+
t = d / 2
|
43
|
+
b = (b * a) % n if u == 1
|
44
|
+
a = a**2 % n
|
45
|
+
d = t
|
46
|
+
end
|
47
|
+
|
48
|
+
if b == 1
|
49
|
+
true
|
50
|
+
else
|
51
|
+
s.times do |i|
|
52
|
+
return true if b == n - 1
|
53
|
+
b = (b * b) % n
|
54
|
+
end
|
55
|
+
(b == n - 1)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def miller_rabin(n)
|
60
|
+
if n.abs < 2
|
61
|
+
false
|
62
|
+
else
|
63
|
+
likely_prime = true
|
64
|
+
# 26 Yields a probability of prime at 99.99999999999998% so lets kick it up a notch.
|
65
|
+
27.times do |i|
|
66
|
+
begin
|
67
|
+
a = rand(n)
|
68
|
+
end while a == 0
|
69
|
+
likely_prime = likely_prime?(a, n)
|
70
|
+
break unless likely_prime
|
71
|
+
end
|
72
|
+
likely_prime
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def next_prime(x)
|
77
|
+
if x < 2
|
78
|
+
2
|
79
|
+
elsif x < 3
|
80
|
+
3
|
81
|
+
elsif x < 5
|
82
|
+
5
|
83
|
+
else
|
84
|
+
x += (x.even? ? 1 : (x % 10 == 3 ? 4 : 2 ))
|
85
|
+
x += (x % 10 == 3 ? 4 : 2 ) until x.prime?
|
86
|
+
x
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
module Prime::MillerRabin::PrimeIntercept
|
93
|
+
|
94
|
+
# Intercept the prime? method. By going right to MillerRabin we can produce a faster result.
|
95
|
+
def prime?(value, *args)
|
96
|
+
args.first.instance_of?(Prime::MillerRabin) ? args.first.prime?(value) : super
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
module Prime::MillerRabin::Default
|
102
|
+
|
103
|
+
module Prime
|
104
|
+
|
105
|
+
# Change the default generator used to be MillerRabin
|
106
|
+
def prime?(value, generator = ::Prime::MillerRabin.new)
|
107
|
+
super
|
108
|
+
end
|
109
|
+
|
110
|
+
def prime_division(value, generator = ::Prime::MillerRabin.new)
|
111
|
+
super
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
module Integer
|
117
|
+
|
118
|
+
def prime_division(generator = ::Prime::MillerRabin.new)
|
119
|
+
super
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'prime_miller_rabin/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "prime_miller_rabin"
|
8
|
+
spec.version = Prime::MillerRabin::VERSION
|
9
|
+
spec.authors = ["Frank Hall"]
|
10
|
+
spec.email = ["ChapterHouse.Dune@gmail.com"]
|
11
|
+
spec.description = %q{Test primes faster than Ruby's default methods by using the Miller-Rabin method.}
|
12
|
+
spec.summary = %q{Test primes faster than Ruby's default methods by using the Miller-Rabin method.}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: prime_miller_rabin
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Frank Hall
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-06-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: Test primes faster than Ruby's default methods by using the Miller-Rabin
|
42
|
+
method.
|
43
|
+
email:
|
44
|
+
- ChapterHouse.Dune@gmail.com
|
45
|
+
executables: []
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- .gitignore
|
50
|
+
- Gemfile
|
51
|
+
- LICENSE.txt
|
52
|
+
- README.md
|
53
|
+
- Rakefile
|
54
|
+
- lib/prime_miller_rabin.rb
|
55
|
+
- lib/prime_miller_rabin/version.rb
|
56
|
+
- prime_miller_rabin.gemspec
|
57
|
+
homepage: ''
|
58
|
+
licenses:
|
59
|
+
- MIT
|
60
|
+
metadata: {}
|
61
|
+
post_install_message:
|
62
|
+
rdoc_options: []
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - '>='
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
requirements: []
|
76
|
+
rubyforge_project:
|
77
|
+
rubygems_version: 2.0.3
|
78
|
+
signing_key:
|
79
|
+
specification_version: 4
|
80
|
+
summary: Test primes faster than Ruby's default methods by using the Miller-Rabin
|
81
|
+
method.
|
82
|
+
test_files: []
|