1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 import time
17
20 self.pool_index = 0
21 self.digest = None
22 self.next_byte = 0
23 if seed is None:
24 try:
25 r = file('/dev/random')
26 try:
27 seed = r.read(16)
28 finally:
29 r.close()
30 except:
31 seed = str(time.time())
32 try:
33 import hashlib
34 self.hash = hashlib.sha1()
35 self.hash_len = 20
36 except:
37 try:
38 import sha
39 self.hash = sha.new()
40 self.hash_len = 20
41 except:
42 import md5
43 self.hash = md5.new()
44 self.hash_len = 16
45 self.pool = '\0' * self.hash_len
46 self.stir(seed)
47
48 - def stir(self, entropy):
49 bytes = [ord(c) for c in self.pool]
50 for c in entropy:
51 if self.pool_index == self.hash_len:
52 self.pool_index = 0
53 b = ord(c) & 0xff
54 bytes[self.pool_index] ^= b
55 self.pool_index += 1
56 self.pool = ''.join([chr(c) for c in bytes])
57
59 if self.digest is None or self.next_byte == self.hash_len:
60 self.hash.update(self.pool)
61 self.digest = self.hash.digest()
62 self.stir(self.digest)
63 self.next_byte = 0
64 value = ord(self.digest[self.next_byte])
65 self.next_byte += 1
66 return value
67
70
73
75 size = last - first + 1
76 if size > 4294967296L:
77 raise ValueError, 'too big'
78 if size > 65536:
79 rand = self.random_32
80 max = 4294967295L
81 elif size > 256:
82 rand = self.random_16
83 max = 65535
84 else:
85 rand = self.random_8
86 max = 255
87 return (first + size * rand() // (max + 1))
88
89 pool = EntropyPool()
90
93
96