Как проигнорировать ошибку и не остановить скрипт? - PullRequest
0 голосов
/ 10 февраля 2020

У меня есть рабочий скрипт (Работает на Python 2.7):

import sys

a=0
b=7
p=0xB12D

x2=0x38F

if (len(sys.argv)>1):
    x1=int(sys.argv[1])
if (len(sys.argv)>2):
    x2=int(sys.argv[2])
if (len(sys.argv)>3):
    p=int(sys.argv[3])
if (len(sys.argv)>4):
    a=int(sys.argv[4])
if (len(sys.argv)>5):
    b=int(sys.argv[5])


def modular_sqrt(a, p):
    """ Find a quadratic residue (mod p) of 'a'. p
        must be an odd prime.

        Solve the congruence of the form:
            x^2 = a (mod p)
        And returns x. Note that p - x is also a root.

        0 is returned is no square root exists for
        these a and p.

        The Tonelli-Shanks algorithm is used (except
        for some simple cases in which the solution
        is known from an identity). This algorithm
        runs in polynomial time (unless the
        generalized Riemann hypothesis is false).
    """
    # Simple cases
    #

    if legendre_symbol(a, p) != 1:
        return 0
    elif a == 0:
        return 0
    elif p == 2:
        return p
    elif p % 4 == 3:
        return pow(a, (p + 1) / 4, p)

    # Partition p-1 to s * 2^e for an odd s (i.e.
    # reduce all the powers of 2 from p-1)
    #
    s = p - 1
    e = 0
    while s % 2 == 0:
        s /= 2
        e += 1

    # Find some 'n' with a legendre symbol n|p = -1.
    # Shouldn't take long.
    #
    n = 2
    while legendre_symbol(n, p) != -1:
        n += 1

    x = pow(a, (s + 1) / 2, p)
    b = pow(a, s, p)
    g = pow(n, s, p)
    r = e

    while True:
        t = b
        m = 0
        for m in xrange(r):
            if t == 1:
                break
            t = pow(t, 2, p)

        if m == 0:
            return x

        gs = pow(g, 2 ** (r - m - 1), p)
        g = (gs * gs) % p
        x = (x * gs) % p
        b = (b * g) % p
        r = m


def legendre_symbol(a, p):
    """ Compute the Legendre symbol a|p using
        Euler's criterion. p is a prime, a is
        relatively prime to p (if p divides
        a, then a|p = 0)


        Returns 1 if a has a square root modulo
        p, -1 otherwise.
    """
    ls = pow(a, (p - 1) / 2, p)
    return -1 if ls == p - 1 else ls

def egcd(a, b):
    if a == 0:
        return (b, 0, 1)
    else:
        g, y, x = egcd(b % a, a)
        return (g, x - (b // a) * y, y)

def modinv(a, m):
    g, x, y = egcd(a, m)
    if g != 1:
        print ("x")
    else:
       return x % m

def hexint(i): return int(i,0)

print "a=",a
print "b=",b
print "p=",p

print "x-point=",x2


# Read numbers from file and put them in an array
with open("List.txt","r") as f:
#   arrX1 = list(map(int,f.readlines()))
    arrX1 = list(map(hexint,f.readlines()))
f.close()

# Open the result file to write to
f = open('Result.txt', 'w')

# Now get x1 for each item in the list of numbers from the file
# then do the calculations
# and write the result

for x1 in arrX1:
    z=(x1**3 + a*x1 +b) % p
    y1=modular_sqrt(z, p)

    z=(x2**3 + a*x2 +b) % p
    y2=modular_sqrt(z, p)

    print "\nP1\t(%d,%d)" % (x1,y1)
    print "P2\t(%d,%d)" % (x2,y2)

    s=((-y2)-y1)* modinv(x2-x1,p) 

    x3=(s**2-x2-x1) % p

    y3=((s*(x2-x3)+y2)) % p

    result =  "\nQ(%d\n,%d)" % (x3,y3)
    f.write(result)

f.close()

Но в этом скрипте возникают ошибки из-за отрицательного значения во время обработки. (То есть при выполнении вычислений по формуле "s =" значение становится отрицательным, и сценарий останавливается.)

Вот ошибка:

Traceback (most recent call last):
  File "E: \ 005.py", line 148, in <module>
    s = ((- y2) -y1) * modinv (x2-x1, p)
TypeError: unsupported operand type (s) for *: 'long' and 'NoneType'
>>>

Мне не нужен мой сценарий остановить, но записать в файл только правильный результат: "Result.txt". И то, что не было правильно проигнорировано и продолжало работать! Можно ли игнорировать эту остановку?

То есть, если происходит ошибка, не останавливать процесс и выполнять другие последовательные команды? Я не очень силен в языке Python и не могу исправить скрипт, чтобы функция пропускала эту ошибку.

1 Ответ

0 голосов
/ 10 февраля 2020

Если вы ожидаете, что функция может вернуть неправильное значение - None - тогда вы должны получить его отдельно и использовать if/else, чтобы пропустить его

value = modinv(x2-x1, p) 

if value is not None:
    s = (-y2-y1) * value

    x3 = (s**2-x2-x1) % p

    y3 = (s*(x2-x3)+y2) % p

    result = "\nQ(%d\n,%d)" % (x3, y3)
    f.write(result)
else:
    print('TypeError for:', x2, x1, p)
    #f.write("\nNo Result")

В конце концов вы можете использовать try/except, чтобы поймать это ошибка

try:
    s = (-y2-y1) * modinv(x2-x1, p) 

    x3 = (s**2-x2-x1) % p

    y3 = (s*(x2-x3)+y2) % p

    result = "\nQ(%d\n,%d)" % (x3, y3)
    f.write(result)
except TypeError:
    print('TypeError for:', x2, x1, p)
    #f.write("\nNo Result")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...