diff options
| author | Jérémy Zurcher <jeremy@asynk.ch> | 2011-08-05 23:38:11 +0200 | 
|---|---|---|
| committer | Jérémy Zurcher <jeremy@asynk.ch> | 2011-08-05 23:38:11 +0200 | 
| commit | 91d70d775dd11a9ec350ca7f3b6d403fa897aadc (patch) | |
| tree | df9d078ded8d5263afc655c1042bce83ea9c1447 /lib | |
| parent | cf5212ac4f013f65af0a3855e50017b3abd8cb25 (diff) | |
| download | ayk-91d70d775dd11a9ec350ca7f3b6d403fa897aadc.zip ayk-91d70d775dd11a9ec350ca7f3b6d403fa897aadc.tar.gz  | |
rename math into maths, add function and specs
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/ayk/maths.rb (renamed from lib/ayk/math.rb) | 177 | 
1 files changed, 125 insertions, 52 deletions
diff --git a/lib/ayk/math.rb b/lib/ayk/maths.rb index 90a3b3a..5084eac 100644 --- a/lib/ayk/math.rb +++ b/lib/ayk/maths.rb @@ -1,14 +1,7 @@  #! /usr/bin/env ruby  # -*- coding: UTF-8 -*- - -#---------------------------------------------------------------------------- -# -# File     : math.rb -# Author   : Jérémy Zurcher <jeremy@asynk.ch> -# Date     : 14/09/09  -# License  :  # -#   Copyright (c) 2009 Jérémy Zurcher +#   Copyright (c) 2009-2011 Jérémy Zurcher  #  #   Permission is hereby granted, free of charge, to any person obtaining  #   a copy of this software and associated documentation files (the @@ -34,9 +27,41 @@  #def prime?  #    ('1'*self) !~ /^1?$|^(11+?)\1+$/  #end -#def Math.gcd(x,y) -#    /^(1+)\1*=\1+$/.match('1'*x+'='+'1'*y)[1].length -#end +# +# return true if is a prime number +def Math.prime? x +    return true if x==2 or x==3 +    return false if x<2 or ( x%2 == 0 ) or ( x%3 == 0 ) +    r = (x**0.5).floor +    d = 5 +    while d<=r +        return false if ( x%d == 0 ) or ( x%(d+2) == 0 ) +        d+=6 +    end +    true +end +# +# return a bits long prime number +def Math.prime bits +    bytes_n,bits_n = bits.divmod 8 +    bytes = [] +    begin +        # n = ( (rand()*Time.now.to_f).to_i & 0xff) | 0x80 random char better than rand(255) + 1 ????? +        # rand currently uses a modified Mersenne Twister with a period of 2**19937-1 +        srand() +        bytes.clear +        bytes_n.times do +            bytes << rand(255)+1 +        end +        bytes << ( ((rand()*Time.now.to_f).to_i & 0xFF | 0x80) >> (8 - bits_n) ) +        n = Bignum.from_bytes bytes.inject(''){|s,b|s+=b.chr} +        n+= 1 if n%2 == 0 +        while not Math::prime? n +            n += 2 +        end +    end while n.bits != bits +    n +end  #  # generate prime numbers < n  def Math.sieve n @@ -50,62 +75,110 @@ def Math.sieve n      sieve.compact  end  # +#def Math.gcd(x,y) +#    /^(1+)\1*=\1+$/.match('1'*x+'='+'1'*y)[1].length +#end +#  # return greater common divisor  def Math.gcd x, y      y,x=x,y if x<y -    while y > 0  -        r = x % y  +    while y > 0 +        r = x % y          x = y          y = r      end      return x  end  # -# return true if is a prime number -def Math.prime? x -#    return false if x <0 -    if x==3 -        return true -    elsif x % 2 == 0 -        return false -    elsif x % 3 == 0 -        return false +def Math.prime_power_modulus(b, p, m) +    if p == 1 +        b % m +    elsif (p & 0x1) == 0 +        t = prime_power_modulus(b, p >> 1, m) +        (t * t) % m      else -        r = (x**0.5).floor -        d = 5 -        while d<r -            if x % d == 0 -                return false -            end -            if x % (d + 2) == 0 -                return false -            end -            d+=6 +        (b * prime_power_modulus(b, p-1, m)) % m +    end +end +# +class Fixnum +    # +    class << self +        def from_bytes bytes +            val = 0 +            idx = 0 +            bytes.each_byte{ |b| +                val += b << 8 * idx +                idx += 1 +            } +            val +        end +    end +    # +    def to_bytes +        str = '' +        int = self +        while int!=0 do +            int,r = int.divmod 256 +            str += r.chr          end -        return true +        str      end +    # +    def bits +        s = self.to_bytes +        while s[-1].ord==0 +            s.slice!(-1) +        end +        bit_len = s.length * 8 +        tmp = s[-1].ord +        while not tmp & 0x80 +            bit_len-=1 +            tmp <<=1 +        end +        bit_len +    end +    #  end  # -# return a bits long prime number -def Math.prime bits -    bytes_n,bits_n = bits.divmod 8 -    bytes = [] -    begin -        # n = ( (rand()*Time.now.to_f).to_i & 0xff) | 0x80 random char better than rand(255) + 1 ????? -        # rand currently uses a modified Mersenne Twister with a period of 2**19937-1 -        srand() -        bytes.clear -        bytes_n.times do -            bytes << rand(255)+1 +class Bignum +    # +    class << self +        def from_bytes bytes +            val = 0 +            idx = 0 +            bytes.each_byte{ |b| +                val += b << 8 * idx +                idx += 1 +            } +            val          end -        bytes << ( ((rand()*Time.now.to_f).to_i & 0xFF | 0x80) >> (8 - bits_n) ) -        n = Bignum.from_bytes( bytes.inject(''){|s,b|s+=b.chr} ) -        puts n -        n+= 1 if n%2 == 0 -        while not Math::prime? n -            n += 2 +    end +    # +    def to_bytes +        str = '' +        bint = self +        while bint!=0 do +            bint,r = bint.divmod 256 +            str += r.chr          end -    end while n.bits != bits -    n +        str +    end +    # +    def bits +        s = self.to_bytes +        while s[-1].ord==0 +            s.slice!(-1) +        end +        bit_len = s.length * 8 +        tmp = s[-1].ord +        while not tmp & 0x80 +            bit_len-=1 +            tmp <<=1 +        end +        bit_len +    end +    #  end  # +#EOF  | 
