Skip to content
This repository was archived by the owner on Sep 12, 2018. It is now read-only.

Commit

Permalink
Reimplemented the RSA::Math.primes method to generate pseudo-primes d…
Browse files Browse the repository at this point in the history
…irectly.

This enables compatibility with Ruby 1.8, where the Prime standard library isn't yet available.

This also has the effect of significantly speeding up other RSA::Math methods relying on prime generation. It appears that Ruby 1.9's pseudo-prime generator implementation is rather inefficient compared to a more straightforward implementation of the same algorithm.
  • Loading branch information
artob committed Sep 9, 2010
1 parent 8bb8e70 commit f79b71c
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 9 deletions.
24 changes: 17 additions & 7 deletions lib/rsa/math.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,29 @@ module Math
class ArithmeticError < ArgumentError; end

##
# Yields the infinite sequence of prime numbers.
# Yields an infinite pseudo-prime number sequence.
#
# This is a pseudo-prime generator that simply yields the initial values
# 2 and 3, followed by all positive integers that are not divisible by 2
# or 3.
#
# It works identically to `Prime::Generator23`, the Ruby 1.9 standard
# library's default pseudo-prime generator implementation.
#
# @example
# RSA::Math.primes.take(5) #=> [2, 3, 5, 7, 11]
#
# @yield [prime] each prime number
# @yieldparam [Integer] prime a prime number
# @return [Enumerator]
# @yield [p] each pseudo-prime number
# @yieldparam [Integer] p a pseudo-prime number
# @return [Enumerator] yielding pseudo-primes
# @see http://ruby-doc.org/core-1.9/classes/Prime.html
def self.primes(&block)
require 'prime' unless defined?(Prime) # Ruby 1.9+ only
primes = Prime::Generator23.new
block_given? ? primes.each(&block) : primes.to_enum
if block_given?
yield 2; yield 3; yield 5
prime, step = 5, 4
loop { yield prime += (step = 6 - step) }
end
enum_for(:primes)
end

##
Expand Down
5 changes: 3 additions & 2 deletions spec/math_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
RSA::Math.primes.should be_an(Enumerator)
end

it "returns the prime number sequence" do
RSA::Math.primes.take(5).should == [2, 3, 5, 7, 11]
it "returns a pseudo-prime number sequence" do
RSA::Math.primes.take(5).should == [2, 3, 5, 7, 11]
RSA::Math.primes.take(1000).should == Prime::Generator23.new.take(1000) if RUBY_VERSION > '1.9' # Ruby 1.9+ only
end
end

Expand Down
2 changes: 2 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
require 'rsa'
include RSA

require 'prime' if RUBY_VERSION > '1.9' # Ruby 1.9+ only

0 comments on commit f79b71c

Please sign in to comment.