Advertisement
Guest User

qsolver

a guest
May 8th, 2020
270
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.51 KB | None | 0 0
  1. from math import *
  2. from time import perf_counter
  3. from decimal import *
  4. getcontext().prec = 192
  5. import sys
  6.  
  7. #could use a segment to determine bitlength or
  8. #otherwise let user set bitlength themselves.
  9. n = 0
  10. m = 0
  11. c = 0
  12. a = 0
  13. b = 0
  14. factorRange = 0
  15.  
  16. pStr = (input("product: ")).replace(",", "")
  17. try:
  18.   p = Decimal(pStr)
  19. except Exception:
  20.   print("no product given. Exiting!")
  21.   exit()
  22.  
  23.  
  24. print("[RECOMMENDED] entering -1 in any field indicates you want qsolver to attempt to guesttimate that value")
  25. print("(use -2 for n if you want it to estimate Q first)")
  26. nStr = input("n: ")
  27. print("(use -2 for m if you want to set m to cutoff)")
  28. mStr = input("m: ")
  29. cStr = input("cutoff: ")
  30. try:
  31.   n = Decimal(nStr)
  32.   m = Decimal(mStr)
  33.   c = Decimal(cStr)
  34. except Exception:
  35.   print("error - invalid number or format. Setting n and m, and cutoff to 0")
  36.   n = Decimal('0.0')
  37.   m = Decimal('0.0')
  38.   c = Decimal('0.0')
  39.  
  40.  
  41. checkPseudo = input("estimate pseudofactors? y|n (or press enter to skip): ")
  42. try:
  43.   if str.lower(checkPseudo) == "y":
  44.     getLower = True
  45.   else:
  46.     getLower = False
  47. except Exception:
  48.   print("skipping pseudo factor checking")
  49.   getLower = False
  50.  
  51. if getLower:
  52.   a = (input("factor a: ")).replace(",", "")
  53.   b = (input("factor b: ")).replace(",", "")
  54.   factorRange = input("factor range: ")
  55.   try:
  56.     a = Decimal(a)
  57.     b = Decimal(b)
  58.     factorRange = Decimal(factorRange)
  59.   except Exception:
  60.     print("error - invalud numbers or format. Skipping pseudo factor check.")
  61.  
  62.  
  63.  
  64. #returns the unit digit and mantissa of n
  65. def sublimate(n):
  66.   _n = str(Decimal(n))
  67.   i = 0
  68.   #then loop until we hit a period
  69.   while i < len(_n):
  70.     if _n[i] == '.':
  71.       break
  72.     i = i + 1
  73.  
  74.   i = i - 1 #back off to the unit digit
  75.  
  76.   if _n[len(_n)-1] == ".":
  77.     #if the last digit in the string is a period it's because it's a whole number
  78.     #so return the digit before it
  79.     return Decimal(_n[len(_n)-2])
  80.   else:
  81.     #otherwise, return up to the last, fractional digit, in the mantissa
  82.     return Decimal(_n[i:len(_n)])
  83.  
  84.  
  85.  
  86.  
  87.  
  88. #find pseudo factor
  89. def findPseudo(x, y, range):
  90.   #print("searching for pseudo factor..")
  91.   if abs(x-y) <= range:
  92.     print("FOUND pseudo factor! x-y: " + str(abs(x-y)))
  93.     return x
  94.   else:
  95.     return None
  96.  
  97.  
  98. #attempts to find a suitable N before solving with n and m
  99. def findN(p):
  100.   w = p.sqrt()
  101.   g = w**(1/p.ln())
  102.   Q = w**g
  103.   q = Q/w
  104.   v = w/q
  105.   n = v-sublimate(w)
  106.   return n
  107.  
  108.  
  109. #solves for n and m given Q
  110. def solveQ(p, N = 0, M = 0, C = 0, a = 0, b = 0, fRange = 0):
  111.   n = 0
  112.   m = 0
  113.   cutoff = 0
  114.   w = p.sqrt()
  115.  
  116.   if N == -1:
  117.     #n = floor(log(p**2))
  118.     n = Decimal(floor(log(p*w)))
  119.   if N == -2:
  120.     n = Decimal(floor(findN(p)))-1
  121.   else:
  122.     n = N
  123.  
  124.   if M == -1:
  125.     m = Decimal(floor(p.ln() ** Decimal(e)))
  126.   elif M== -2:
  127.     m = Decimal(ceil(Decimal(ceil(Decimal(p.ln())*w)).sqrt())) #uses cutoff method
  128.   else:
  129.     m = M
  130.  
  131.   if C < 1:
  132.     cutoff = Decimal(ceil(Decimal(ceil(Decimal(log(p))*w)).sqrt()))
  133.   else:
  134.     cutoff = C
  135.  
  136.   print("n: " + str(n))
  137.   print("m: "+ str(m))
  138.   print("c: " + str(cutoff))
  139.   print("a: " + str(a) + ",  b: " + str(b) + ",  range: " + str(fRange))
  140.  
  141.   i=0
  142.   t=0
  143.   while n < cutoff:
  144.     Q = ((w/(Decimal(sublimate(w))+n))*w)
  145.     q = (w/Decimal((sublimate(w))+n))
  146.     #m = Decimal(floor(p.ln() ** Decimal(e)))
  147.     m = 0
  148.     total = 0
  149.     #while m > (total):
  150.     while m < cutoff:
  151.       r = Q/(q-m)
  152.       #print("r: " + str(r))
  153.       if a > 0:
  154.         f = findPseudo(Decimal(abs(r)), a, fRange)
  155.         if f != None:
  156.           print("pseudo factor f: " + str(f)[:32] + ", t: " + str(t) + ",  n: " + str(n) + ",  m: " + str(m))
  157.           return f
  158.       elif b > 0:
  159.         f = findPseudo(Decimal(abs(r)), b, fRange)
  160.         if f != None:
  161.           print("pseudo factor f: " + str(f)[:32] + ", t: " + str(t) + ",  n: " + str(n) + ",  m: " + str(m))
  162.           return f
  163.  
  164.  
  165.       #n2 = floor(w/q)
  166.       r2 = r
  167.       r2ceil = Decimal(ceil(r2))
  168.       r2floor = Decimal(floor(r2))
  169.       r2ceilAdd = Decimal(r2ceil+1)
  170.       r2ceilSub = Decimal(r2ceil-1)
  171.       r2floorAdd = Decimal(r2floor+1)
  172.       r2floorSub = Decimal(r2floor-1)
  173.       f = 0
  174.       while f < 2:
  175.         #in-range checks. Basically see if we're close at any point
  176.         if (p/r2ceil)%1 == 0:
  177.           print("\n[SEQ] FOUND FACTOR! = " + str(r2ceil))
  178.           print("r2CEIL, n: " + str(n) + ",  m: " + str(m) + ",  t: " + str(t))
  179.           print("-m") if f<1 else print("+m")
  180.           print("cutoff: " + str(cutoff))
  181.           return abs(r2ceil)
  182.         if (p/r2floor)%1 == 0:
  183.           print("\n[SEQ] FOUND FACTOR! = " + str(r2floor))
  184.           print("r2FLOOR, n: " + str(n) + ",  m: " + str(m) + ",  t: " + str(t))
  185.           print("-m") if f<1 else print("+m")
  186.           print("cutoff: " + str(cutoff))
  187.           return abs(r2floor)
  188.         if (p/r2ceilAdd)%1 == 0:
  189.           print("\n[SEQ] FOUND FACTOR! = " + str(r2ceilAdd))
  190.           print("r2CEILADD, n: " + str(n) + ",  m: " + str(m) + ",  t: " + str(t))
  191.           print("-m") if f<1 else print("+m")
  192.           print("cutoff: " + str(cutoff))
  193.           return abs(r2ceilAdd)
  194.         if (p/r2ceilSub)%1 == 0:
  195.           print("\n[SEQ] FOUND FACTOR! = " + str(r2ceilSub))
  196.           print("r2CEILSUB, n: " + str(n) + ",  m: " + str(m) + ",  t: " + str(t))
  197.           print("-m") if f<1 else print("+m")
  198.           print("cutoff: " + str(cutoff))
  199.           return abs(r2ceilSub)
  200.         if (p/r2floorAdd)%1 == 0:
  201.           print("\n[SEQ] FOUND FACTOR! = " + str(r2floorAdd))
  202.           print("r2FLOORADD, n: " + str(n) + ",  m: " + str(m) + ",  t: " + str(t))
  203.           print("-m") if f<1 else print("+m")
  204.           print("cutoff: " + str(cutoff))
  205.           return abs(r2floorAdd)
  206.         if (p/r2floorSub)%1 == 0:
  207.           print("\n[SEQ] FOUND FACTOR! = " + str(r2floorSub))
  208.           print("r2FLOORSUB, n: " + str(n) + ",  m: " + str(m) + ",  t: " + str(t))
  209.           print("-m") if f<1 else print("+m")
  210.           print("cutoff: " + str(cutoff))
  211.           return abs(r2floorSub)
  212.        
  213.         #same thing but with +m now instead of -m
  214.         r = Q/(q+m)
  215.         r2 = r
  216.         r2ceil = Decimal(ceil(r2))
  217.         r2floor = Decimal(floor(r2))
  218.         r2ceilAdd = Decimal(r2ceil+1)
  219.         r2ceilSub = Decimal(r2ceil-1)
  220.         r2floorAdd = Decimal(r2floor+1)
  221.         r2floorSub = Decimal(r2floor-1)
  222.         f = f + 1
  223.         #if r2ceil < 2 or r2floor < 2 or r2ceilAdd < 2 or r2ceilSub < 2 or r2floorAdd < 2 or r2floorSub < 2:
  224.         #  break
  225.         #print("r: " + str(r))
  226.      
  227.       if i >= 10000:
  228.         sys.stdout.write(".")
  229.         sys.stdout.flush()
  230.         i=0
  231.    
  232.       i=i+1
  233.    
  234.    
  235.       #print("r: " + str(r))
  236.       if r <= 0:
  237.         break
  238.      
  239.       if r != 1 and r != 0 and r != p and (p/r)%1 == 0: #and p/(p/r)%1 == 0:
  240.         print("\nFOUND factor: " + str(r))
  241.         print("n: " + str(n) + ",  m: " + str(m) + ",  t: " + str(t))
  242.         print("-m") if f<1 else print("+m")
  243.         print("cutoff: " + str(cutoff))
  244.         return r
  245.      
  246.      
  247.      
  248.       #m = m - 1
  249.       m = m + 1
  250.       t = t + 1
  251.    
  252.     n = n + 1
  253.     t = t + 1
  254.  
  255.   print("NO FACTOR FOUND! (or an exception happened)")
  256.   print("cutoff: " + str(cutoff))
  257.   return -1 #no such value was found
  258.  
  259.  
  260. f = -1
  261. _ = input("press ENTER to begin search.")
  262. startTime = perf_counter()
  263. f = solveQ(p, n, m, c, a, b, factorRange)
  264.  
  265. print("time: " + str(perf_counter() - startTime) + "s\n")
  266.  
  267. print("NOTE - if the solver fails to find a factor, try increasing the cutoff first.")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement