Browse Source

Miller Rabin (may still be buggy)

Petra Lamborn 5 years ago
parent
commit
a64b558e13
1 changed files with 92 additions and 1 deletions
  1. 92
    1
      bot.py

+ 92
- 1
bot.py View File

@@ -1,3 +1,94 @@
1 1
 import random
2
+from math import floor, log
2 3
 
3
-print(random.randint(0,12))
4
+pto100 = [
5
+    2,3,5,7,11,13,17,19,23,29,31,37,41,
6
+     43,47,53,59,61,67,71,73,79,83,89,97
7
+]
8
+
9
+def in_100(x):
10
+    """Check if x is in the primes less than 100 i.e., in the first 25 primes.
11
+    Useful for e.g. the first step in Baillie–PSW.
12
+    """
13
+    return x in pto100
14
+
15
+def hund_div(x):
16
+    """Check if x is divisible by any of the 25 primes less than 100. Returns 0
17
+    if there is no such divisor, otherwise returns the first divisor.
18
+    """
19
+    for v in pto100:
20
+        if v >= x:
21
+            return 0
22
+        if x % v == 0:
23
+            return v
24
+    return 0
25
+
26
+def trd(x):
27
+    """Express x as 2^r * d. Returns two values, r and d.
28
+    """
29
+    count = 0
30
+    xc = x
31
+    while xc % 2 == 0:
32
+        count = count + 1
33
+        xc = xc // 2
34
+    return count, xc
35
+
36
+def MillerRabinRandom(n, k):
37
+    """Carry out a Miller-Rabin test on n with k iterations, choosing random
38
+    values for a.
39
+    """
40
+    r, d = trd(n-1)
41
+    for iter in range(k):
42
+        a = random.randint(2, n - 2)
43
+        x = pow(a, d, n)
44
+        if x == 1 or x == n - 1:
45
+            continue
46
+        compo = True
47
+        for iterb in range(r - 1):
48
+            x = pow(x, 2, n)
49
+            if x == n - 1:
50
+                compo = False
51
+                break
52
+        if compo:
53
+            return True
54
+    return False
55
+
56
+def MillerRabin(n, base):
57
+    """Carry out a Miller-Rabin test on n with a specified base.
58
+    """
59
+    #print(n, base)
60
+    r, d = trd(n-1)
61
+    #print(r, d)
62
+    a = base
63
+    x = pow(a, d, n)
64
+    #print(x)
65
+    if x == 1 or x == n - 1:
66
+        #print("First")
67
+        return False
68
+    for iterb in range(r - 1):
69
+        x = pow(x, 2, n)
70
+        if x == n - 1:
71
+            #print("Second,", iterb, x)
72
+            return False
73
+    #print("True")
74
+    return True
75
+
76
+#for i in range(2, 100):
77
+#    print(i, hund_div(i))
78
+#
79
+#print()
80
+
81
+#Print pseudoprimes greater than 100 for each base, from base 1 to 15
82
+for base in range(2, 16):
83
+    print("{}:".format(base))
84
+    for i in range(2, 10000):
85
+        if base > i - 2 or i % 2 == 0:
86
+            continue
87
+        if MillerRabin(i, base) == (hund_div(i) == 0):
88
+            print(i, hund_div(i), MillerRabin(i, base))
89
+    print()
90
+
91
+MillerRabin(28, 3)
92
+print(pow(3, 27, 28))
93
+print(pow(3, 27))
94
+print(pow(3, 27) % 28)