Advertisement
jukaukor

alkulukugeneraattori.py

Mar 29th, 2019
181
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.40 KB | None | 0 0
  1. # Ohjelma generoi suuren bittimääräältään halutukokoisen käyttäen
  2. # alkuluvun testauksessa käytetään Miller-Rabinin menetelmään
  3. # joka on virheetön lukua 341550071728321 pienemmille
  4. # ja sitä suuremmille virheen mahdollisuus äärimmäisen pieni
  5. # suuria alkulukuja käytetään julkisen avaimen salauksessa
  6. # ohjelma tehty käyttäen lähdettä https://inventwithpython.com/hacking/chapter23.html
  7. # Juhani Kaukoranta 29.3.2019
  8.  
  9. import random
  10. import math
  11. import time
  12. # numba nopeuttaa laskentaa pitkillä salasanoilla
  13. # halutessasi voit poistaa risuaidan alla olevista 'from numba import jit' ja '@jit(parallel=True)'
  14. #from numba import jit
  15.  
  16. # *** Pääohjelman käyttämät funktiot ***
  17.  
  18. # alkuluvun generointi käyttäen annettua bittipituutta
  19. #@jit(parallel=True)
  20. def generateLargePrime(keysize):
  21. # Return a random prime number of keysize bits in size.
  22. while True:
  23. num = random.randrange(2**(keysize-1), 2**(keysize))
  24. if is_prime(num):
  25. return num
  26.  
  27. # Miller-Rabin correct and probabilistic composite, prime test
  28. # correct answers for n less than 341550071728321
  29. # and then reverting to the probabilistic form
  30. # source https://rosettacode.org/wiki/Miller%E2%80%93Rabin_primality_test#Python
  31.  
  32. def _try_composite(a, d, n, s):
  33. if pow(a, d, n) == 1:
  34. return False
  35. for i in range(s):
  36. if pow(a, 2**i * d, n) == n-1:
  37. return False
  38. return True # n is definitely composite
  39.  
  40. def is_prime(n, _precision_for_huge_n=16):
  41. # _known_lowprimes are primes < 1000
  42.  
  43.  
  44. if n in _known_lowprimes:
  45. return True
  46. if any((n % p) == 0 for p in _known_lowprimes) or n in (0, 1):
  47. return False
  48. d, s = n - 1, 0
  49. while not d % 2:
  50. d, s = d >> 1, s + 1
  51. # Returns exact according to http://primes.utm.edu/prove/prove2_3.html
  52. if n < 1373653:
  53. return not any(_try_composite(a, d, n, s) for a in (2, 3))
  54. if n < 25326001:
  55. return not any(_try_composite(a, d, n, s) for a in (2, 3, 5))
  56. if n < 118670087467:
  57. if n == 3215031751:
  58. return False
  59. return not any(_try_composite(a, d, n, s) for a in (2, 3, 5, 7))
  60. if n < 2152302898747:
  61. return not any(_try_composite(a, d, n, s) for a in (2, 3, 5, 7, 11))
  62. if n < 3474749660383:
  63. return not any(_try_composite(a, d, n, s) for a in (2, 3, 5, 7, 11, 13))
  64. if n < 341550071728321:
  65. return not any(_try_composite(a, d, n, s) for a in (2, 3, 5, 7, 11, 13, 17))
  66. # otherwise
  67. return not any(_try_composite(a, d, n, s)
  68. for a in _known_lowprimes[:_precision_for_huge_n])
  69.  
  70. # lasketaan valmiiksi _known_lowprimes eli alkuluvut < 1000
  71. # nopeuttaa huomattavasti tarkistusta, onko luku alkuluku
  72. _known_lowprimes = [2, 3]
  73. _known_lowprimes += [x for x in range(5, 1000, 2) if is_prime(x)]
  74. # *** Pääohjelma ***
  75. print("Ohjelma generoi bittimäärältään halutunkokoisen alkuluvun")
  76. bittipituus = int(input("Anna salaukseen haluttu bittimäärä, esim 256, 512,1024,2048 "))
  77. time0 = time.perf_counter()
  78. alkuluku = generateLargePrime(bittipituus)
  79. time1 = time.perf_counter()
  80. print("Annettu bittipituus oli ",bittipituus)
  81. print("Generoitu alkuluku on ",alkuluku)
  82. print("Alkulukuvun pituus on ",len(str(alkuluku))," numeroa")
  83. print("Tarkistus alkuluvun bittisyydelle: ", math.log(alkuluku,2))
  84. print("Laskenta-aika oli ",time1-time0," sekuntia")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement