From c93bc4b37ec462e3eb7011375648fadfc3471c8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksy=20Wr=C3=B3blewski?= Date: Tue, 26 Jun 2018 15:26:07 +0000 Subject: [PATCH] Zaktualizuj 'hw3.py' zmiana outputu --- hw3.py | 348 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 176 insertions(+), 172 deletions(-) diff --git a/hw3.py b/hw3.py index 3fc464c..3a045e1 100644 --- a/hw3.py +++ b/hw3.py @@ -1,173 +1,177 @@ -from sys import argv -from fractions import gcd - -class Polynomial(): - def __init__(self, lst, mod): - self.poly = list(map(lambda x: x % mod, lst)) - self.mod = mod - self.normalize() - def normalize(self): - while self.poly and self.poly[-1] == 0: - self.poly.pop() - - #zwraca jednomian stopnia n - @staticmethod - def Monomial(n, c, mod): - zeros = [0]*n - zeros.append(c) - return Polynomial(zeros, mod) - - def __add__(self, p2): - p1 = self - len_p1, len_p2= len(p1.poly), len(p2.poly) - res = [0] * max(len_p1, len_p2) - if len_p1 > len_p2: - for _ in range(len_p1-len_p2): - p2.poly.append(0) - else: - for _ in range(len_p2-len_p1): - p1.poly.append(0) - - for i in range(len(res)): - res[i] = (p1.poly[i] + p2.poly[i]) % self.mod - return Polynomial(res, self.mod) - - def __sub__(self, p2): - p1 = self - res = [] - len_p2 = len(p2.poly) - for i in range(len(p1.poly)): - if i < len_p2: - res.append(p1.poly[i] - p2.poly[i] % self.mod) - else: - res.append(p1.poly[i]) - return Polynomial(res, self.mod) - - def __mul__(self, p2): - res = [0]*(len(self.poly)+len(p2.poly)-1) - for i, x1 in enumerate(self.poly): - for j, x2 in enumerate(p2.poly): - res[i+j] += x1 * x2 % self.mod - return Polynomial(res, self.mod) - - def __truediv__(self, p2): - p1 = self - m = self.mod - - if len(p1.poly) < len(p2.poly): - return p1 - - if len(p2.poly) == 0: - raise ZeroDivisionError - - divisor_coeff = p2.poly[-1] - divisor_exp = len(p2.poly) - 1 - while len(p1.poly) >= len(p2.poly): - max_coeff_p1 = p1.poly[-1] #wspolczynnik przy najwyzszej potedze - try: - tmp_coeff = modDiv(max_coeff_p1, divisor_coeff, m) - except ZeroDivisionError as e: - raise e - - tmp_exp = len(p1.poly)-1 - divisor_exp - tmp = [0] * tmp_exp - tmp.append(tmp_coeff) - sub = Polynomial(tmp, m) * p2 - p1 = p1 - sub - p1.normalize() - return Polynomial(p1.poly, m) - -def modDiv(a, b, m): # a*b^-1 (mod m) - if gcd(b, m) != 1: - raise ZeroDivisionError - else: - return (a * modinv(b, m)) % m -#rozszerzony algorytm euklidesa -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) - return x % m -#lista stringow binarnych -> lista intow 0/1 -def bin_str_to_list(lst): - res = [] - for elem in lst: - for ch in elem: - res.append(int(ch)) - return res - -def mod8format(lst): - while len(lst) % 8 != 0: - lst.append(0) - return lst - -def to_bin(x): - data = bin(ord(x)).replace('b', '') - while len(data) != 8: - if len(data) < 8: - data = str(0) + data - else: - data.replace(data[0], '') - return data - -def to_ascii_val(lst): - sum = 0 - for i in range(len(lst)): - if lst[i] == 1: - sum += 2**(7-i) - return chr(sum) - -def data(): - p = bin_str_to_list(list(map(lambda x: to_bin(x), m))) - p.reverse() - Lx = Polynomial([1] * 16, 2) #L(x) - X16 = Polynomial.Monomial(16, 1, 2) #X^16 - Gx = Polynomial([1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,1], 2) #G(x) - return (p, Lx, X16, Gx) - -def fcs(m): - p, Lx, X16, Gx = data() - Mx = Polynomial(p, 2) #M(x) #X^16 - Xnsub16 = Polynomial.Monomial(len(m)*8, 1, 2) #X^(n-16) - rhs = Xnsub16 * Lx - lhs = X16 * Mx - xor = lhs + rhs - fcs = xor/Gx - #algorytm dzielenia ucina zera, trzeba dopelnic do 16 bitow - for i in range(16 - len(fcs.poly)): - fcs.poly.append(0) - fcs.poly.reverse() - return fcs.poly - -def check(m): - p, Lx, X16, Gx = data() - Xn = Polynomial.Monomial(len(p), 1, 2) #X^n - Cx = Polynomial(p, 2) - Cx = X16 * Cx - Cx.poly = mod8format(Cx.poly) - Sx = (Cx + Xn * Lx) / Gx - if Sx.poly == []: - return True - return False - -def main(): - global m - m = list(argv[1]) - mode = argv[2] # flagi -e -d (encode, decode) - if mode == '-e': - res = fcs(m) - fcs_ch1 = to_ascii_val(res[:8]) - fcs_ch2 = to_ascii_val(res[8:]) - m.append(fcs_ch1) - m.append(fcs_ch2) - print(''.join(m)) - elif mode == '-d': - print(check(m)) - -if __name__ == '__main__': +from sys import argv +from fractions import gcd +from ast import literal_eval + +class Polynomial(): + def __init__(self, lst, mod): + self.poly = list(map(lambda x: x % mod, lst)) + self.mod = mod + self.normalize() + def normalize(self): + while self.poly and self.poly[-1] == 0: + self.poly.pop() + + #zwraca jednomian stopnia n + @staticmethod + def Monomial(n, c, mod): + zeros = [0]*n + zeros.append(c) + return Polynomial(zeros, mod) + + def __add__(self, p2): + p1 = self + len_p1, len_p2= len(p1.poly), len(p2.poly) + res = [0] * max(len_p1, len_p2) + if len_p1 > len_p2: + for _ in range(len_p1-len_p2): + p2.poly.append(0) + else: + for _ in range(len_p2-len_p1): + p1.poly.append(0) + + for i in range(len(res)): + res[i] = (p1.poly[i] + p2.poly[i]) % self.mod + return Polynomial(res, self.mod) + + def __sub__(self, p2): + p1 = self + res = [] + len_p2 = len(p2.poly) + for i in range(len(p1.poly)): + if i < len_p2: + res.append(p1.poly[i] - p2.poly[i] % self.mod) + else: + res.append(p1.poly[i]) + return Polynomial(res, self.mod) + + def __mul__(self, p2): + res = [0]*(len(self.poly)+len(p2.poly)-1) + for i, x1 in enumerate(self.poly): + for j, x2 in enumerate(p2.poly): + res[i+j] += x1 * x2 % self.mod + return Polynomial(res, self.mod) + + def __truediv__(self, p2): + p1 = self + m = self.mod + + if len(p1.poly) < len(p2.poly): + return p1 + + if len(p2.poly) == 0: + raise ZeroDivisionError + + divisor_coeff = p2.poly[-1] + divisor_exp = len(p2.poly) - 1 + while len(p1.poly) >= len(p2.poly): + max_coeff_p1 = p1.poly[-1] #wspolczynnik przy najwyzszej potedze + try: + tmp_coeff = modDiv(max_coeff_p1, divisor_coeff, m) + except ZeroDivisionError as e: + raise e + + tmp_exp = len(p1.poly)-1 - divisor_exp + tmp = [0] * tmp_exp + tmp.append(tmp_coeff) + sub = Polynomial(tmp, m) * p2 + p1 = p1 - sub + p1.normalize() + return Polynomial(p1.poly, m) + +def modDiv(a, b, m): # a*b^-1 (mod m) + if gcd(b, m) != 1: + raise ZeroDivisionError + else: + return (a * modinv(b, m)) % m +#rozszerzony algorytm euklidesa +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) + return x % m +#lista stringow binarnych -> lista intow 0/1 +def bin_str_to_list(lst): + res = [] + for elem in lst: + for ch in elem: + res.append(int(ch)) + return res + +def mod8format(lst): + while len(lst) % 8 != 0: + lst.append(0) + return lst + +def to_bin(x): + data = bin(ord(x)).replace('b', '') + while len(data) != 8: + if len(data) < 8: + data = str(0) + data + else: + data = data[1:] + return data + +def to_ascii_val(lst): + sum = 0 + for i in range(len(lst)): + if lst[i] == 1: + sum += 2**(7-i) + + return chr(sum) + +def data(): + p = bin_str_to_list(list(map(lambda x: to_bin(x), m))) + p.reverse() + Lx = Polynomial([1] * 16, 2) #L(x) + X16 = Polynomial.Monomial(16, 1, 2) #X^16 + Gx = Polynomial([1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,1], 2) #G(x) + return (p, Lx, X16, Gx) + +def fcs(m): + p, Lx, X16, Gx = data() + Mx = Polynomial(p, 2) #M(x) #X^16 + Xnsub16 = Polynomial.Monomial(len(m)*8, 1, 2) #X^(n-16) + rhs = Xnsub16 * Lx + lhs = X16 * Mx + xor = lhs + rhs + fcs = xor/Gx + #algorytm dzielenia ucina zera, trzeba dopelnic do 16 bitow + for i in range(16 - len(fcs.poly)): + fcs.poly.append(0) + fcs.poly.reverse() + return fcs.poly + +def check(m): + p, Lx, X16, Gx = data() + Xn = Polynomial.Monomial(len(p), 1, 2) #X^n + Cx = Polynomial(p, 2) + Cx = X16 * Cx + Cx.poly = mod8format(Cx.poly) + Sx = (Cx + Xn * Lx) / Gx + if Sx.poly == []: + return True + return False + +def main(): + global m + m = list(argv[2]) + mode = argv[1] # flagi -e -d (encode, decode) + if mode == '-e': + res = fcs(m) + fcs_ch1 = to_ascii_val(res[:8]) + fcs_ch2 = to_ascii_val(res[8:]) + m.append(fcs_ch1) + m.append(fcs_ch2) + print(m) + elif mode == '-d': + to_check = literal_eval(argv[3]) + m += to_check + print(check(m)) + +if __name__ == '__main__': main() \ No newline at end of file