首页 > 解决方案 > Python 3 中大数字的精确数学

问题描述

我正在尝试使用 Python实现类似于Shamir 的秘密共享的加密系统。本质上,我的代码将生成一个点列表,可用于在这些点形成的梯度的 y 截距处查找密码。密码是 ASCII 中的数字(每个 ASCII 字符使用两位数),因此对于更大的密码来说是一个相当大的数字。例如,密码ThisIsAPassword将生成如下所示的点列表:

x    y
9556 66707086867915126140753213946756441607861037300900
4083 28502040182447127964404994111341362715565457349000
9684 67600608880657662915204624898507424633297513499300
9197 64201036847801292531159022293017356403707170463200

需要明确的是,这些点是在随机选择的斜率上生成的(这很好,因为重要的是 y 截距)。

问题出现在尝试制作程序来解码密码时。由于数字的大小,使用普通数学,Python 无法准确找到密码。这是我的代码:

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()

输出(使用密码“ThisIsAPassword”):

͉)3 ǢΜĩũć»¢ǔ¼

通常,我的代码将使用较短的密码,例如“pass”或“word”,但较大的数字可能无法以将它们转换为 ASCII 所需的精确精度进行计算。任何使用精确数学或其他方法的解决方案?

另外这里是生成点的代码,以防它很重要:

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 < 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()

标签: pythonpython-3.x

解决方案


应该只能使用基于整数的数学来做到这一点:

def findYint(x,y):
    return (y[0] * (x[1] - x[0]) - (y[1] - y[0]) * x[0])  // (x[1] - x[0])

这样您就可以避免浮点运算及其具有的精度约束。


推荐阅读