2017-06-21 2 views
0

Je travaille actuellement sur un programme de chiffrement pour un cours de python pour débutants. On nous a d'abord dit de créer une fonction qui retournerait la position d'une lettre donnée, en utilisant une chaîne de l'alphabet comme référence (c'est ma fonction alphabet_position.) Ensuite, on nous a dit de faire une fonction qui permettrait une seule lettre à faire pivoter par un nombre choisi (c'est ma fonction rotate_character). Troisièmement, nous avons été chargés de créer un chiffrement césar de base en utilisant les deux fonctions précédentes. Tous ceux que j'ai pu faire travailler comme démontré par mon code ci-dessous.Python Vigenere fonctionne, mais je ne peux pas tenir compte des espaces et des caractères non alphabétiques en utilisant les fonctions

La vigenere, cependant, s'avère beaucoup plus difficile. J'ai été capable de trouver un extrait de code que j'ai pu modifier avec ma première fonction (alphabet_position) pour faire du travail si seulement des caractères alphabétiques sont utilisés, mais dès que j'entre un caractère non alphabétique (comme! Ou?) Je reçois un retour de ValueError: Substring Not found. Lorsque le programme rencontre ces caractères non alphabétiques, la clé est censée les passer et porter le Nième caractère de la touche au caractère alphabétique suivant. Je suppose que la réponse réside dans l'incorporation de ma fonction rotate_character dans ma fonction Encrypt, mais je ne sais pas comment faire, car la fonction rotate_character attend un caractère alphabétique, et la fonction vigenere transforme ce paramètre en un int avant courir à travers.

Un conseil? Et comme je suis un nouveau programmeur, je serai heureux de prendre toute autre critique utile sur mes pratiques de codage que vous pouvez instiller! `

> #Create function alphabet_position(letter) to turn letter into number 
> #such as a=0 or e=4, using lowercase to make sure case doesnt matter. 
    alphabet = "abcdefghijklmnopqrstuvwxyz" 
    def alphabet_position(letter): 
>  lower_letter = letter.lower() #Makes any input lowercase. 
>  return alphabet.index(lower_letter) #Returns the position of input 
              as a number. 
> 
> def rotate_character(char, rot): 
>  if char.isalpha(): 
>   a = alphabet_position(char); 
>   a = (a + rot) % (int(len(alphabet)));   #needs modulo 
>   a = (alphabet[a]); 
>   if char.isupper(): 
>    a = a.title() 
>   return a 
>  else: 
>  return char 
> 
> def caesar(text, rot): 
>  list1 = "" 
>  for char in text: 
>   list1 += rotate_character(char, rot) 
>  return list1 
> 
> def vigenere(text,key):  
    m = len(key) 
> 
> newList = "" 
> 
> for i in range(len(text)):  
     text_position = alphabet_position(text[i])  
     key_position = alphabet_position(key[i % m])  
     value = (text_position + key_position) % 26   
     newList += alphabet[value]  
    return newList 
> 
> def main(): 
>  x = input("Type a message: ") 
>  y = input("Rotate by: ") 
>  result = vigenere(x, y) 
>  print (result) 
> 
> if __name__ == '__main__': 
     main() 

Répondre

1

Non, vous ne pas besoin de la fonction de rotation plus. Vous avez juste besoin d'ajouter directement tout caractère qui n'est pas dans l'alphabet à la liste, puis d'ignorer la partie de cryptage.

maintenant une sous-optimale façon de le faire est d'utiliser if ... in ...:

if text[i] in alphabet: 
    # do your thing 
else: 
    newList += text[i] 

Bien sûr plus optimale est de ne passer par l'alphabet une fois et utilisez une variable:

pt_c = text[i] 
pt_i = alphabet.find(pt_c) # returns -1 instead of an error when not found 
if pt_i == -1: 
    newList += pt_c 
else: 
    newList += pt_c 
    # do your thing *with the given index* 

Cette ne fera aucune différence dans l'exécution pour un chiffrement Vigenère bien sûr. Mais cela vous montre comment penser à une programmation efficace pour plus tard: il n'y a pas besoin de chercher deux fois.

Vous pouvez également continue la boucle au lieu d'avoir une instruction else:

pt_c = text[i] 
pt_i = alphabet.find(pt_c) # returns -1 instead of an error when not found 
if pt_i == -1: 
    continue 
# do your thing with the given index 

cela va rendre la profondeur d'enfoncement de la boucle (la quantité de champs) moins, avec l'effet secondaire malheureux de faire votre boucle plus complexe (création d'un point de sortie local).

+0

J'ai essayé la première option que vous avez donnée, et cela a fonctionné parfaitement! Je vais jouer avec les autres pour voir comment ils fonctionnent aussi. Dans l'intérêt d'expérimenter pour apprendre, avez-vous vu comment je pourrais modifier ma fonction rotate_character pour l'utiliser dans ma fonction vigenere? Sinon, c'est bon. Merci pour l'aide tellement! –

+0

Bien sûr, regardez à nouveau les 4 instructions dans la boucle 'for' et la fonction' rotate_character'. Ne sont-ils pas vaguement familiers? Que se passerait-il si vous utilisiez 'key_position' comme paramètre' rot'? –

+0

Merci! Je vais commencer à expérimenter avec tout cela pour voir comment ils fonctionnent dans mon script! –