From 916515e5e2c8fbad088c9d90ae3081eb0b52a976 Mon Sep 17 00:00:00 2001 From: Rnhmjoj Date: Fri, 6 Dec 2013 19:57:11 +0100 Subject: [PATCH] Miglioramenti vari MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Sostituito il test di primalità con il Miller-Rabin (k=64) (più veloce ma non deterministico) * Utlizzati generatori in sostituzione alle tuple (più veloce) * Sostituita la concatenazione di stringhe con join (più veloce) * Correzioni per PEP8 --- License.txt | 2 +- README.md | 9 +++---- crittografia/__init__.py | 2 +- crittografia/alfabeto.py | 48 +++++++++++++++++++++--------------- crittografia/numeri.py | 53 ++++++++++++++++++++++++++-------------- crittografia/unicode.py | 42 ++++++++++++++++++------------- 6 files changed, 94 insertions(+), 62 deletions(-) diff --git a/License.txt b/License.txt index d39a202..740078f 100644 --- a/License.txt +++ b/License.txt @@ -1,6 +1,6 @@ * Crittografia * - * Pacchetto di funzioni crittografiche in python 3 + * Pacchetto di cifrari storici e famosi in python 3 * * Dual licensed under the MIT and GPL licenses: * http://www.opensource.org/licenses/mit-license.php diff --git a/README.md b/README.md index 4e83515..9956aa6 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,10 @@ -Crittografia -============ +# Crittografia -Pacchetto di funzioni crittografiche in python 3 ------------------------------------------------- + +## Pacchetto di cifrari storici e famosi in python 3 ### Informazioni -Una raccolta di cifrari storici e famosi in python. +Una raccolta di cifrari storici e famosi in python 3. Per ora contiene: * ROT13; * Cifrario di Vigenère; diff --git a/crittografia/__init__.py b/crittografia/__init__.py index 563a44f..23c3a28 100644 --- a/crittografia/__init__.py +++ b/crittografia/__init__.py @@ -1,3 +1,3 @@ from .alfabeto import * from .unicode import * -from .numeri import * \ No newline at end of file +from .numeri import * diff --git a/crittografia/alfabeto.py b/crittografia/alfabeto.py index 1fade23..6779d62 100644 --- a/crittografia/alfabeto.py +++ b/crittografia/alfabeto.py @@ -1,7 +1,7 @@ from .numeri import * -alfabeto = tuple("abcdefghijklmnopqrstuvwxyz") -ordinale = dict([(k, i) for i, k in enumerate(alfabeto)]) +alfa = tuple("abcdefghijklmnopqrstuvwxyz") +ord = {k: i for i, k in enumerate(alfa)} class codifica: @@ -30,10 +30,12 @@ class codifica: minore della stringa. (verme) """ self.stringa = self.stringa.lower().replace(" ", "") - cifrata = "" + cifrata = [] for i, lettera in enumerate(self.stringa): - cifrata += alfabeto[(ordinale[lettera] + ordinale[verme[i % len(verme)]]) % 26] - return cifrata + cifrata.append( + alfa[(ord[lettera] + ord[verme[i % len(verme)]]) % 26] + ) + return "".join(cifrata) def gödel(self, primo): """ @@ -42,9 +44,9 @@ class codifica: """ self.stringa = self.stringa.lower().replace(" ", "") cifrata = 1 - sequenza = primi.lista(primo, len(self.stringa)) + sequenza = primi.primi(primo, len(self.stringa)) for i, lettera in enumerate(self.stringa): - cifrata *= sequenza[i] ** (ordinale[lettera] + 1) + cifrata *= next(sequenza) ** (ord[lettera] + 1) return cifrata def vernam(self, pad=()): @@ -54,12 +56,14 @@ class codifica: uno in automatico. """ self.stringa = self.stringa.lower().replace(" ", "") - cifrata = "" + cifrata = [] if pad is (): pad = generatore.onetimepad(len(self.stringa)) for i, lettera in enumerate(self.stringa): - cifrata += alfabeto[(ordinale[lettera] + pad[i]) % 26] - return cifrata, pad + cifrata.append( + alfa[(ord[lettera] + pad[i]) % 26] + ) + return "".join(cifrata), pad class decodifica: @@ -90,10 +94,12 @@ class decodifica: Fornire la chiave usata per crittografare la stringa. (verme) """ self.stringa = self.stringa.lower().replace(" ", "") - decifrata = "" + decifrata = [] for i, lettera in enumerate(self.stringa): - decifrata += (alfabeto[(ordinale[lettera] - ordinale[verme[i % len(verme)]]) % 26]) - return decifrata + decifrata.append( + alfa[(ord[lettera] - ord[verme[i % len(verme)]]) % 26] + ) + return "".join(decifrata) def gödel(self, primo, n): """ @@ -101,14 +107,14 @@ class decodifica: Specificare un numero primo di partenza e la lunghezza della stringa. """ - decifrata = "" - for i in primi.lista(primo, n): + decifrata = [] + for i in primi.primi(primo, n): lettera = -1 while self.numero % i == 0: self.numero /= i lettera += 1 - decifrata += alfabeto[lettera % 26] - return decifrata + decifrata.append(alfa[lettera % 26]) + return "".join(decifrata) def vernam(self, pad): """ @@ -116,7 +122,9 @@ class decodifica: Fornire il one-time-pad usato per crittografare la stringa. """ self.stringa = self.stringa.lower().replace(" ", "") - cifrata = "" + cifrata = [] for i, lettera in enumerate(self.stringa): - cifrata += alfabeto[(ordinale[lettera] - pad[i]) % 26] - return cifrata + cifrata.append( + alfa[(ord[lettera] - pad[i]) % 26] + ) + return "".join(cifrata) diff --git a/crittografia/numeri.py b/crittografia/numeri.py index e70351c..fd57aa6 100644 --- a/crittografia/numeri.py +++ b/crittografia/numeri.py @@ -12,32 +12,49 @@ opzioni = { class primi: - def primo(n): + def primo(n, k=64): """ + Test di primalità probabilistico Miller-Rabin. Restituisce True se n è primo altrimenti restituisce False. """ - for i in range(3, int(math.sqrt(n)) + 1, 2): - if n % i == 0: - return False - return True + if n == 2: + return True + if n % 2 == 0: + return False - def prossimo(n): + s = 0 + d = n - 1 + while True: + q, r = divmod(d, 2) + if r == 1: + break + s += 1 + d = q + + for i in range(k): + a = random.randrange(2, n) + if pow(a, d, n) == 1: + return True + for i in range(s): + if pow(a, 2 ** i * d, n) == n - 1: + return True + return False + + def primi(p, n): """ - Restituisce il più piccolo numero primo maggiore di n. + Restituisce gli n numeri primi succesivi a p. [Generatore] """ - if n % 2 == 0: - n += 1 + if p % 2 == 0: + p += 1 + i = 0 while True: - n += 2 - if primi.primo(n): - yield n - - def lista(p, n): - """ - Restituisce una n-tupla con i numeri primi maggiori di p. - """ - return tuple([p for p in itertools.islice(primi.prossimo(p), n)]) + if i == n: + break + if primi.primo(p): + i += 1 + yield p + p += 2 class generatore: diff --git a/crittografia/unicode.py b/crittografia/unicode.py index f3aee79..6c2afac 100644 --- a/crittografia/unicode.py +++ b/crittografia/unicode.py @@ -28,10 +28,12 @@ class codifica: Fornire una chiave alfabetica di lunghezza minore della stringa. (verme) """ - cifrata = "" + cifrata = [] for i, lettera in enumerate(self.stringa): - cifrata += chr((ord(lettera) + ord(verme[i % len(verme)])) % max) - return cifrata + cifrata.append( + chr((ord(lettera) + ord(verme[i % len(verme)])) % max) + ) + return "".join(cifrata) def gödel(self, primo): """ @@ -39,9 +41,9 @@ class codifica: Specificare un numero primo di partenza. """ cifrata = 1 - sequenza = primi.lista(primo, len(self.stringa)) + sequenza = primi.primi(primo, len(self.stringa)) for i, lettera in enumerate(self.stringa): - cifrata *= sequenza[i] ** (ord(lettera) + 1) + cifrata *= next(sequenza) ** (ord(lettera) + 1) return cifrata def vernam(self, pad=()): @@ -50,12 +52,14 @@ class codifica: Se non si fornisce un one-time-pad ne viene generato uno in automatico. """ - cifrata = "" + cifrata = [] if pad is (): pad = generatore.onetimepad(len(self.stringa)) for i, lettera in enumerate(self.stringa): - cifrata += chr((ord(lettera) + pad[i]) % max) - return cifrata, pad + cifrata.append( + chr((ord(lettera) + pad[i]) % max) + ) + return "".join(cifrata), pad class decodifica: @@ -85,10 +89,12 @@ class decodifica: Cifrario di vigenère Fornire la chiave usata per crittografare la stringa. (verme) """ - decifrata = "" + decifrata = [] for i, lettera in enumerate(self.stringa): - decifrata += chr((ord(lettera) - ord(verme[i % len(verme)])) % max) - return decifrata + decifrata.append( + chr((ord(lettera) - ord(verme[i % len(verme)])) % max) + ) + return "".join(decifrata) def gödel(self, primo, n): """ @@ -96,13 +102,13 @@ class decodifica: Specificare un numero primo di partenza e la lunghezza della stringa. """ - decifrata = "" - for i in primi.lista(primo, n): + decifrata = [] + for i in primi.primi(primo, n): lettera = -1 while self.numero % i == 0: self.numero /= i lettera += 1 - decifrata += chr(lettera % max) + decifrata.append(chr(lettera % max)) return decifrata def vernam(self, pad): @@ -110,7 +116,9 @@ class decodifica: Cifrario di Vernam Fornire il one-time-pad usato per crittografare la stringa. """ - cifrata = "" + cifrata = [] for i, lettera in enumerate(self.stringa): - cifrata += chr((ord(lettera) - pad[i]) % max) - return cifrata + cifrata.append( + chr((ord(lettera) - pad[i]) % max) + ) + return "".join(cifrata)