diff --git a/polynomial.py b/polynomial.py index 0a360c260de3150d6d6dc18a60cbc4ff2f6ad2a4..a40bb9a63f90bbfa8a8fe5aed18877fd285371a8 100644 --- a/polynomial.py +++ b/polynomial.py @@ -11,7 +11,8 @@ def unicode_superscripts(number): Returns: str: The unicode superscripts string. """ - exponent_dict = {"0": "⁰", "1": "¹", "2": "²", "3": "³", "4": "⁴", "5": "⁵", "6": "⁶", "7": "⁷", "8": "⁸", "9": "⁹"} + exponent_dict = {"0": "⁰", "1": "¹", "2": "²", "3": "³", + "4": "⁴", "5": "⁵", "6": "⁶", "7": "⁷", "8": "⁸", "9": "⁹"} return ("⁻" if number < 0 else "") + "".join(exponent_dict[x] for x in str(abs(number))) @@ -59,12 +60,11 @@ class Polynomial: """ a = list(self.value) b = list(other.value) - c = [] - # itertools pad 0 to the lowest list - for (a, b) in itertools.zip_longest(a, b, fillvalue=0): - c.append(a + b) + # itertools pad 0 to the lowest list. + for (ai, bi) in itertools.zip_longest(a, b, fillvalue=0): + c.append(ai + bi) return Polynomial(tuple(c)) def __mul__(self, other): @@ -83,6 +83,7 @@ class Polynomial: for i in range(len(a)): for j in range(len(b)): + # Sum of the product of a[i] by b[j] at exponent i + j. c[i + j] += a[i] * b[j] return Polynomial(tuple(c)) @@ -93,18 +94,14 @@ class Polynomial: other (int): The modulo to apply. Returns: - Polynomial: The result of the modolu operation. + Polynomial: The result of the modulo operation. """ - a = list(self.value) - result = [0] * len(a) + result = list(self.value) - for i in range(len(a)): - result[i] = a[i] % other - for i in reversed(range(len(result))): - if result[i] == 0: - del result[i] - else: - break + for i in range(len(result)): + result[i] %= other + while result[-1] == 0 and len(result) > 1: + result = result[:-1] return Polynomial(tuple(result)) def __str__(self): @@ -145,25 +142,29 @@ def get_bezout_coefficients(a, b): x = [1, 0] y = [0, 1] q = [0, 0] - i = 1 + i = 2 - while r[i] > 0: - i += 1 + while True: r.append(r[i - 2] % r[i - 1]) + # Continue until the rest is equal to 0 + if r[i] == 0: + break + q.append(int(r[i - 2] / r[i - 1])) + x.append(x[i - 2] - q[i] * x[i - 1]) + y.append(y[i - 2] - q[i] * y[i - 1]) + + i += 1 - if r[i] > 0: - x.append(x[i - 2] - q[i] * x[i - 1]) - y.append(y[i - 2] - q[i] * y[i - 1]) return x[-1], y[-1] def modular_inverse(a, n): - """Compute the modular inverse of a number a modolu n. + """Compute the modular inverse of a number a modulo n. Args: a (int): The number to reverse. - n (int): The modolu. + n (int): The modulo. Returns: int: The reversed number. @@ -196,7 +197,7 @@ def compute_lagrange_polynomial(points, prime_number): for j, (xj, _) in enumerate(points): if j != i: Li_polynomial *= Polynomial((-xj, 1)) - Li_polynomial *= Polynomial((modular_inverse(xi - xj, prime_number),)) + Li_polynomial *= Polynomial((modular_inverse(xi - xj, prime_number))) Li_polynomial *= Polynomial((yi,)) L_polynomial += Li_polynomial return L_polynomial % prime_number @@ -218,13 +219,13 @@ def reed_solomon(points, data_length, last_error_index, prime_number): # Parse each combination of points possible (exclude the correct points) for x in itertools.combinations(points[: last_error_index + 1], combination_length): - nb_valid_points = 0 # Create a sublist of points with all corrects points and the current combination of points - sub_points = list(x) + points[last_error_index + 1 :] + sub_points = list(x) + points[last_error_index + 1:] # Create the lagrange polynomial with the sublist of points lagrange = compute_lagrange_polynomial(sub_points, prime_number) + nb_valid_points = 0 # Parse each points to verify if the polynomial is correct for p in points: x = p[0] @@ -235,7 +236,8 @@ def reed_solomon(points, data_length, last_error_index, prime_number): nb_valid_points += 1 # Verify if we have enough valid points, so it must be equal or higher than m + n points - if nb_valid_points >= data_length + (len(points) - data_length) // 2: # // = euclid division + # // = euclid division + if nb_valid_points >= data_length + (len(points) - data_length) // 2: # Decode the message output = "" for i in range(data_length):