3190 - Vigenere

From Bitnami MediaWiki

Vigenere[edit | edit source]

La fel ca cifrul Cezar, cifrul Vigenere deplasează literele, dar acesta folosește o deplasare multiplă. Cheia este constituită din câțiva întregi ki, unde 0 ≤ ki ≤ 25. Aceşti întregi pot fi, de exemplu, k = (21, 4, 2 19, 14, 17). Această cheie ar provoca deplasare primei litere cu 21, c1 = p1 + 21 (mod 26), a celei de-a doua cu 4, c2 = p2 + 4 (mod 26), ş.a.m.d. până la sfârşitul cheii și apoi de la început, din nou.

Pentru o memorare mai ușoară cheia este de regulă dată printr-un cuvânt – cheia de mai sus corespunde cuvântului vector, litera 'v'” corespondând numărului 21 (numerotarea începe de la 0), litera 'e' cu 4, etc. Un exemplu de cifru Vigenere:

Textul clar: thisisanexampleofthevigenerecipher

Cheia: vector

Textul cifrat: olklwjvrgqodkpghtkcixbuviitxqzklgk

Cerinţa[edit | edit source]

Se citesc două texte a și b cu lungimea maximă de 255 de caractere. Să se afișeze textul după 
aplicarea cifrului Vigenere la textul a cu cheia b.

Date de intrare[edit | edit source]

Fișierul de intrare vigenerein.txt conține pe prima linie textul a iar pe a doua linie textul b.

Date de ieșire[edit | edit source]

Fișierul de ieșire vigenereout.txt va conține pe prima linie rezultatul criptării.

Restricţii şi precizări[edit | edit source]

  • lungimea lui b ⩽ Lungimea lui a ⩽ 255;
  • cele două șiruri vor conține doar litere mici din alfabetul englez.

Exemplu 1[edit | edit source]

vigenerein.txt
pbinfo
dio
vigenereout.txt
Datele de intrare corespund restrictiilor impuse
sjwqnc


Exemplu 2[edit | edit source]

vigenerein.txt
abc123
vigenereout.txt
Datele de intrare nu corespund restrictiilor impuse


Explicatie[edit | edit source]

În Cifrul Vigenere începem numărătoarea caracterelor din cheie de la 0, astfel, caracterul 'd' din cheie deplasează caractrrul corespunzător din text cu 3 caractere; astfel, 'p' devine 's'. Acest procedeu se repetă și pentru restul șirului.

Rezolvare[edit | edit source]

<syntaxhighlight lang="python" line> def vigenere(a, b, c):

   # Aplică cifrul Vigenere pe textul a cu cheia b
   alfabet = 'abcdefghijklmnopqrstuvwxyz'
   if c == 1:
       return .join([alfabet[(alfabet.index(a[i]) + alfabet.index(b[i % len(b)])) % 26] for i in range(len(a))])
   else:
       return .join([alfabet[(alfabet.index(a[i]) - alfabet.index(b[i % len(b)])) % 26] for i in range(len(a))])


def main():

   with open('vigenerein.txt', 'r') as fin, open('vigenereout.txt', 'w') as fout:
       a = fin.readline().strip()
       b = fin.readline().strip()
       # Verifică dacă textele respectă restricțiile
       if len(a) > 255 or len(b) > len(a) or not a.islower() or not b.islower():
           fout.write("Datele de intrare nu corespund restrictiilor impuse\n")
           return
       fout.write("Datele de intrare corespund restrictiilor impuse\n")
       # Aplică cifrul Vigenere pe textul a cu cheia b și scrie rezultatul în fișierul de ieșire
       fout.write(vigenere(a, b, 1) + '\n')


if __name__ == "__main__":

   main()


</syntaxhighlight>