A
download ISAAC.rb
Language: Ruby
LOC: 130
Project Info
IOWA
Server: RubyForge
Type: cvs
...Forge\i\iowa\iowa\iowa\src\
   Application.rb
   ApplicationStats.rb
   Association.rb
   BindingsParser.rb
   Client.rb
   Component.rb
   ComponentProxy.rb
   config.rb
   Context.rb
   DbPool.rb
   DynamicElements.rb
   Element.rb
   Form.rb
   HTTPServer.rb
   ISAAC.rb
   KeyValueCoding.rb
   LRUCache.rb
   PageStore.rb
   read_multipart.rb
   Request.rb
   SciTE.properties
   Session.rb
   SessionStats.rb
   SessionStore.rb
   Tag.rb
   TemplateParser.rb
   WEBrickServlet.rb

module Crypt

	# ISAAC is a fast, strong random number generator.  Details on the
	# algorithm can be found here: http://burtleburtle.net/bob/rand/isaac.html
	# This provides a consistent and capable algorithm for producing
	# independent streams of quality random numbers.

	class ISAAC

		attr_accessor :randrsl, :randcnt
		attr_accessor :mm, :aa, :bb, :cc

		# When a Crypt::ISAAC object is created, it needs to be seeded for
		# random number generation.  If the system has a /dev/urandom file,
		# that will be used to do the seeding.  If it does not, the system
		# will fall back to a simplistic initialization mechanism.

		def initialize
			@mm = []
			@randrsl = []
			# Best initialization of the generator would be by pulling
			# numbers from /dev/random.
			if (FileTest.exist? '/dev/urandom')
				File.open('/dev/urandom','r') do |r|
					256.times do |t|
						z = r.read(4)
						x = z.unpack('V')[0]
						@randrsl[t] = x
					end
				end
			else
				# If urandom isn't available, the standard Ruby PRNG makes an
				# adequate fallback.
				256.times do |t|
					@randrsl[t] = Kernel.rand(2147483647)
				end
			end
			randinit(true)
			nil
		end

		# Works just like the standard rand() function.  If called with an
		# integer argument, rand() will return positive random number in
		# the range of 0 to (argument - 1).  If called without an integer
		# argument, rand() returns a positive floating point number less than 1.
  
		def rand(*num)
			if (@randcnt == 1)
				isaac
				@randcnt = 256
			end
			@randcnt -= 1
			if num[0].to_i > 0
				@randrsl[@randcnt].modulo(num[0])
			else
				".#{@randrsl[@randcnt]}".to_f
			end
		end

		def isaac
			i = 0
			x = 0
			y = 0

			@cc += 1
			@bb += @cc
			@bb & 0xffffffff

			while (i < 256) do 
				x = @mm[i]
				@aa = (@mm[(i + 128) & 255] + (@aa^(@aa << 13)) ) & 0xffffffff
				@mm[i] = y = (@mm[(x>>2)&255] + @aa + @bb ) & 0xffffffff
				@randrsl[i] = @bb = (@mm[(y>>10)&255] + x ) & 0xffffffff
				i += 1

				x = @mm[i]
				@aa = (@mm[(i+128)&255] + (@aa^(0x03ffffff & (@aa >> 6))) ) & 0xffffffff
				@mm[i] = y = (@mm[(x>>2)&255] + @aa + @bb ) & 0xffffffff
				@randrsl[i] = @bb = (@mm[(y>>10)&255] + x ) & 0xffffffff
				i += 1

				x = @mm[i]
				@aa = (@mm[(i + 128)&255] + (@aa^(@aa << 2)) ) & 0xffffffff
				@mm[i] = y = (@mm[(x>>2)&255] + @aa + @bb ) & 0xffffffff
				@randrsl[i] = @bb = (@mm[(y>>10)&255] + x ) & 0xffffffff
				i += 1

				x = @mm[i]
				@aa = (@mm[(i+128)&255] + (@aa^(0x0000ffff & (@aa >> 16))) ) & 0xffffffff
				@mm[i] = y = (@mm[(x>>2)&255] + @aa + @bb ) & 0xffffffff
				@randrsl[i] = @bb = (@mm[(y>>10)&255] + x ) & 0xffffffff
				i += 1
			end
		end

		def randinit(flag)
			i = 0
			a = 0
			b = 0
			c = 0
			d = 0
			e = 0
			f = 0
			g = 0
			@aa = @bb = @cc = 0
			a = b = c = d = e = f = g = h = 0x9e3779b9

			while (i < 4) do
				a ^= b<<1; d += a; b += c
				b ^= 0x3fffffff & (c>>2); e += b; c += d
				c ^= d << 8; f += c; d += e
				d ^= 0x0000ffff & (e >> 16); g += d; e += f
				e ^= f << 10; h += e; f += g
				f ^= 0x0fffffff & (g >> 4); a += f; g += h
				g ^= h << 8; b += g; h += a
				h ^= 0x007fffff & (a >> 9); c += h; a += b
				i += 1
			end

			i = 0
			while (i < 256) do
				if (flag)
					a+=@randrsl[i  ].to_i; b+=@randrsl[i+1].to_i;
					c+=@randrsl[i+2]; d+=@randrsl[i+3];
					e+=@randrsl[i+4]; f+=@randrsl[i+5];
					g+=@randrsl[i+6]; h+=@randrsl[i+7];
				end

				a^=b<<11; d+=a; b+=c;
				b^=0x3fffffff & (c>>2);  e+=b; c+=d;
				c^=d<<8;  f+=c; d+=e;
				d^=0x0000ffff & (e>>16); g+=d; e+=f;
				e^=f<<10; h+=e; f+=g;
				f^=0x0fffffff & (g>>4);  a+=f; g+=h;
				g^=h<<8;  b+=g; h+=a;
				h^=0x007fffff & (a>>9);  c+=h; a+=b;
				@mm[i]=a;@mm[i+1]=b; @mm[i+2]=c; @mm[i+3]=d;
				@mm[i+4]=e; @mm[i+5]=f; @mm[i+6]=g; @mm[i+7]=h;
				i += 8
			end

			if flag
				i = 0
				while (i < 256)
					a+=@mm[i  ]; b+=@mm[i+1]; c+=@mm[i+2]; d+=@mm[i+3];
					e+=@mm[i+4]; f+=@mm[i+5]; g+=@mm[i+6]; h+=@mm[i+7];
					a^=b<<11; d+=a; b+=c;
					b^=0x3fffffff & (c>>2);  e+=b; c+=d;
					c^=d<<8;  f+=c; d+=e;
					d^=0x0000ffff & (e>>16); g+=d; e+=f;
					e^=f<<10; h+=e; f+=g;
					f^=0x0fffffff & (g>>4);  a+=f; g+=h;
					g^=h<<8;  b+=g; h+=a;
					h^=0x007fffff & (a>>9);  c+=h; a+=b;
					@mm[i  ]=a; @mm[i+1]=b; @mm[i+2]=c; @mm[i+3]=d;
					@mm[i+4]=e; @mm[i+5]=f; @mm[i+6]=g; @mm[i+7]=h;
					i += 8
				end
			end

  		isaac()
   		@randcnt=256;        # /* prepare to use the first set of results */
		end
	end
end

About Koders | Resources | Downloads | Support | Black Duck | Terms of Service | DMCA | Privacy Policy | Contact Us