title: Exact math with big numbers in Python 3
body: <p>I'm trying to implement a system for encryption similar to <a href="https://en.wikipedia.org/wiki/Shamir%27s_Secret_Sharing" rel="nofollow noreferrer">Shamir's Secret Sharing</a> using Python. Essentially, I have code that will generate a list of points that can be used to find a password at the y-intercept of the gradient formed by these points. The password is a number in ASCII (using two digits per ASCII character), thus is gets to be a pretty big number with larger passwords. For example, the password <em>ThisIsAPassword</em> will generate a list of points that looks like this:</p>
  
  <pre><code>x    y
  9556 66707086867915126140753213946756441607861037300900
  4083 28502040182447127964404994111341362715565457349000
  9684 67600608880657662915204624898507424633297513499300
  9197 64201036847801292531159022293017356403707170463200
  </code></pre>
  
  <p><em>To be clear, these points are generated upon a randomly chosen slope (this is fine since it's the y-intercept that matters).</em></p>
  
  <p>The problem arises in trying to make a program to decode a password. Using normal math, Python is unable to accurately find the password because of the size of the numbers. Here's the code I have:</p>
  
  <pre><code>def findYint(x,y):
      slope = (y[1] - y[0]) / (x[1] - x[0])
      yint = int(y[0] - slope * x[0])
      return yint
  
  def asciiToString(num):
      chars = [num[i:i+3] for i in range(0, len(num), 3)]
  
      return ''.join(chr(int(i)) for i in chars)
  
  def main():
      fi = open('pass.txt','r')
      x,y = [], []
      for i in fi:
          row = i.split()
          x.append(int(row[0]))
          y.append(int(row[1]))
      fi.close()
      yint = findYint(x,y)
      pword = asciiToString(str(yint))
  
      print(pword)
  
  main()
  </code></pre>
  
  <p>Output (with the password "ThisIsAPassword"):</p>
  
  <pre><code>͉)3 ǢΜĩũć»¢ǔ¼
  </code></pre>
  
  <p>Typically my code will work with shorter passwords such as "pass" or "word", but the bigger numbers presumably aren't computed with the exact accuracy needed to convert them into ASCII. Any solutions for using either precise math or something else?</p>
  
  <p>Also here's the code for generating points in case it's important:</p>
  
  <pre><code>import random
  
  def encryptWord(word):
      numlist = []
      for i in range(len(word)):
          numlist.append(str(ord(word[i])).zfill(3))
      num = int("".join(numlist))
      return num
  
  def createPoints(pwd, pts):
      yint = pwd
      gradient = pwd*random.randint(10,100)
      xvals = []
      yvals = []
      for i in range(pts):
          n = random.randint(1000,10000)
          xvals.append(n)
          yvals.append(((n) * gradient) + pwd)
  
      return xvals, yvals
  
  def main():
      pword = input("Enter a password to encrypt: ")
      pword = encryptWord(pword)
      numpoints = int(input("How many points to generate? "))
      if numpoints &lt; 2:
          numpoints = 2
      xpts, ypts = createPoints(pword, numpoints)
  
      fi = open("pass.txt","w")
      for i in range(len(xpts)):
          fi.write(str(xpts[i]))
          fi.write(' ')
          fi.write(str(ypts[i]))
          fi.write('\n')
      fi.close()
      print("Sent to file (pass.txt)")
  main()
  </code></pre>