<jupyter_start><jupyter_text>Partie 1 : Code de César  Implementation  Le code suivant contient deux fonctions principales : `encryptMessage` et `decryptMessage`.Ces fonctions permet d'encoder et de decoder un string donnée. L'encryption se fait de facon classique par decalage d'alphabet. La clé donnée est le nombre de decalage. La fonction `convertAlphabets` permet de convertir un texte entre deux alphabets.La fonction `shiftAlphabet` permet de décaler les éléments d'une matrice en faisant une rotation. C'est l'équivalent de decaler la roue interne du code de César.<jupyter_code>alphabet_string = string.printable

alphabetListOrdered = list(alphabet_string)

numberListOrdered = list(map(ord, alphabetListOrdered))

def convertAlphabets(messageCharNumList, numList, numListToConvert, encrypt = True) :
    index = 0
    newList = []
    for val in messageCharNumList:
      indexOfLetter = numListToConvert.index(val)
      newList.append(numList[indexOfLetter])

      index += 1
    if encrypt :
      return ' '.join(map(chr,newList))
    else : 
      return ''.join(map(chr,newList))

def shiftAlphabet(listToShift, keyShift):
  keyShift = keyShift % len(listToShift)
  return listToShift[keyShift:] + listToShift[:keyShift]<jupyter_output><empty_output><jupyter_text>Pour la fonction d'encryption, on utilisera l'alphabet de tout les caracteres imprimable en ascii donnée par `string.printable`.<jupyter_code>string.printable
def encryptMessage(m, shiftKey):

  alphabet_string = string.printable

  alphabetListOrdered = list(alphabet_string)

  numberListOrdered = list(map(ord, alphabetListOrdered))

  alphabetListShuffled = shiftAlphabet(list(alphabetListOrdered), shiftKey)

  numberListShuffled = list(map(ord, alphabetListShuffled))

  return convertAlphabets(list(map(ord, list(m))), numberListShuffled, numberListOrdered)
def decryptMessage(m, shiftKey):
  m = m.replace(' ', '')
  alphabet_string = string.printable

  alphabetListOrdered = list(alphabet_string)

  numberListOrdered = list(map(ord, alphabetListOrdered))

  alphabetListShuffled = list(alphabetListOrdered)

  alphabetListShuffled = shiftAlphabet(list(alphabetListOrdered), shiftKey)

  numberListShuffled = list(map(ord, alphabetListShuffled))

  return convertAlphabets(list(map(ord, list(m))), numberListOrdered, numberListShuffled, False)<jupyter_output><empty_output><jupyter_text>En dessous est un exemple d'encryption et de decryption.<jupyter_code>m = "Vous savez, moi je ne crois pas qu'il y ait de bonne ou de mauvaise situation. Moi, si je devais resumer ma vie aujourd'hui avec vous, je dirais que c'est d'abord des rencontres. Des gens qui m'ont tendu la main, peut-etre a un moment ou je ne pouvais pas, ou j'etais seul chez moi"
m<jupyter_output><empty_output><jupyter_text>On encrypte le texte plus haut au moins d'une clé de valeur `4051`<jupyter_code>e = encryptMessage(m, 4501)
e<jupyter_output>[49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 58, 59, 60, 61, 62, 63, 64, 91, 92, 93, 94, 95, 96, 123, 124, 125, 126, 32, 9, 10, 13, 11, 12, 48]<jupyter_text>On verifie que la decryption marche bien quand on remet la clé.<jupyter_code>d = decryptMessage(e, 4501)
d<jupyter_output><empty_output><jupyter_text>Exercice : Cracker un cypher par décalage avec l'analyse de fréquence Voici un cypher généré avec l'algorithme d'encryption de cypher encryptMessage.Le but est d'arriver a decrypter le message grace a l'analyse de frequence des caracteres du message. Le message code est en anglais, donc un morceau de texte anglais vous est donne pour que vous puissez comparer les frequences.<jupyter_code># Ceci est le message codé à cracker.
# Des espaces sont laissés expres pour permettre de bien reconnaitre les caracteres

# Attention aux caracteres speciaux d'ascii. E.g. `\r` est bien compté comme 1 caractere de lalphabet.

cypher = "Z C D M P C i W M S i B G Q A S Q Q i R F C i P C Q M J S R G M L \r i J C R i K C i N J y A C i z C D M P C i W M S i M L C i M P i R U M i R F G L E Q \r i ' i U y L R i W M S i R M i S L B C P Q R y L B i R U M i R F G L E Q i T C P W i A J C y P J W i y L B i R M i A M L Q G B C P i R F C K i D P M K i R F C i Q y K C i N M G L R i M D i T G C U i D P M K i U F G A F i ' i y K i N J y A G L E i R F C K i z C D M P C i W M S \x0c i ' i y Q I i W M S i R M i A M L Q G B C P i G R i D P M K i K W i N M G L R i M D i T G C U \r i z C A y S Q C i G D i W M S i y N N P M T C i M D i G R \r i W M S i U G J J i z C i C L H M G L C B i R M i A y P P W i M S R i y J J i ' i Q y W \x0c i ' R i U G J J i z C i y i E P C y R i P C Q N M L Q G z G J G R W \x0c i < F C P C i y P C i N C M N J C i U F M i y Q I i K C i U F C R F C P i ' i y K i R F C i Q y K C i K y L i R F y R i ' i U y Q i G L i p x q o \r i M P i U F C R F C P i R F C P C i F y Q i z C C L i y L W i A F y L E C i G L i K C \x0c i [ M S i y P C i P G E F R i G L i y Q I G L E i R F y R i O S C Q R G M L \x0c i * C R i K C \r i F M U C T C P \r i F y Q R C L i R M i y Q Q S P C i R F y R i ' i y K i R F C i Q y K C i % y L B F G i y Q i ' i U y Q i G L i p x q o \x0c i ' i F y T C i L M R i A F y L E C B i G L i y L W i D S L B y K C L R y J i P C Q N C A R \x0c i ' i y R R y A F i R F C i Q y K C i G K N M P R y L A C i R M i L M L T G M J C L A C i R F y R i ' i B G B i R F C L \x0c i ' D i y R i y J J \r i K W i C K N F y Q G Q i M L i G R i F y Q i E P M U L i Q R P M L E C P \x0c i < F C P C i G Q i L M i P C y J i A M L R P y B G A R G M L i z C R U C C L i R F C i N P C Q C L R i P C Q M J S R G M L i y L B i K W i N P C T G M S Q i U P G R G L E Q i y L B i S R R C P y L A C Q \x0c i - A A y Q G M L Q i J G I C i R F C i N P C Q C L R i B M i L M R i M A A S P i G L i C T C P W z M B W } Q i y L B i z S R i P y P C J W i G L i y L W z M B W } Q i J G D C \x0c i ' i U y L R i W M S i R M i I L M U i y L B i D C C J i R F y R i R F C P C i G Q i L M R F G L E i z S R i N S P C Q R i Y F G K Q y i G L i y J J i R F y R i ' i y K i Q y W G L E i y L B i B M G L E i R M B y W \x0c i < F C i B P y D R i P C Q M J S R G M L i M D i R F C i ? M P I G L E i ! M K K G R R C C i G Q i z y Q C B i M L i Y F G K Q y \r i R F C i A M L R C K N J y R C B i Q R P S E E J C i Q G K G J y P J W i F y Q i G R Q i P M M R Q i G L i Y F G K Q y \x0c i ' D \r i R F C P C D M P C \r i R F C P C i G Q i y L W i y K M L E i W M S i U F M i F y Q i J M Q R i D y G R F i G L i Y F G K Q y i M P i G Q i U C y P G C B i M D i G R \r i J C R i F G K i L M R i T M R C i D M P i R F G Q i P C Q M J S R G M L \x0c`"

# Le code ici permet de transformer le cypher en tableau, enlevant au passage tout les espaces entre chaque caracteres

cypherList = list(cypher)[0::2]
cypherList<jupyter_output><empty_output><jupyter_text>Pour vous aider, voici un morceau de discours en anglais sur lequel vous pouvez faire une premiere analyse de frequences de caracteres.Le texte est assez long pour etre representatif d'une distribution classique de la langue anglaise.Votre histogramme devrait ressembler a celui sur la page web suivante : https://www3.nd.edu/~busiforc/handouts/cryptography/letterfrequencies.html<jupyter_code>englishText = "I am the First Accused.I hold a Bachelor's Degree in Arts and practised as an attorney in Johannesburg for a number of years in partnership with <NAME>. I am a convicted prisoner serving five years for leaving the country without a permit and for inciting people to go on strike at the end of May 1961. At the outset, I want to say that the suggestion made by the State in its opening that the struggle in South Africa is under the influence of foreigners or communists is wholly incorrect. I have done whatever I did, both as an individual and as a leader of my people, because of my experience in South Africa and my own proudly felt African background, and not because of what any outsider might have said. In my youth in the Transkei I listened to the elders of my tribe telling stories of the old days. Amongst the tales they related to me were those of wars fought by our ancestors in defence of the fatherland. The names of Dingane and Bambata, Hintsa and Makana, Squngthi and Dalasile, Moshoeshoe and Sekhukhuni, were praised as the glory of the entire African nation. I hoped then that life might offer me the opportunity to serve my people and make my own humble contribution to their freedom struggle. This is what has motivated me in all that I have done in relation to the charges made against me in this case. Having said this, I must deal immediately and at some length with the question of violence. Some of the things so far told to the Court are true and some are untrue. I do not, however, deny that I planned sabotage. I did not plan it in a spirit of recklessness, nor because I have any love of violence. I planned it as a result of a calm and sober assessment of the political situation that had arisen after many years of tyranny, exploitation, and oppression of my people by the Whites."<jupyter_output><empty_output><jupyter_text>**Consigne** :Comparer la frequence d'apparition des caracteres du cypher et du discours.Par simplicité, triez les tableaux dans l'ordre alphabetique.Il faut ensuite que vous decaliez l'alphabet du cypher jusqu'a que les deux distributions se superposent.Vous pouvez utiliser la fonction `shiftAlphabet` donnée plus haut.Ce décalage sera donc la clé d'encryption et de decryption!<jupyter_code># Zone a coder en dessous<jupyter_output><empty_output><jupyter_text>Partie 2 : Code de <NAME>ire  Implementation Voici une legere modification des fonctions d'encryptions du debut de l'exercice.La seule difference etant qu'au lieu de mélanger par décalage, la position de chaque lettre est aléatoire<jupyter_code>def convertAlphabetsRand(messageCharNumList, numList, numListToConvert, encrypt = True) :
    index = 0
    newList = []
    for val in messageCharNumList:
      indexOfLetter = numListToConvert.index(val)
      newList.append(numList[indexOfLetter])

      index += 1
    if encrypt :
      return ' '.join(map(chr,newList))
    else : 
      return ''.join(map(chr,newList))

def encryptMessageRand(m, seedKey):

  alphabet_string = string.printable

  alphabetListOrdered = list(alphabet_string)

  numberListOrdered = list(map(ord, alphabetListOrdered))

  alphabetListShuffled = list(alphabetListOrdered)

  def seed():
    return seedKey

  random.shuffle(alphabetListShuffled, seed)

  numberListShuffled = list(map(ord, alphabetListShuffled))

  return convertAlphabetsRand(list(map(ord, list(m))), numberListShuffled, numberListOrdered)

def decryptMessageRand(m, seedKey):
  m = m.replace(' ', '')
  alphabet_string = string.printable

  alphabetListOrdered = list(alphabet_string)

  numberListOrdered = list(map(ord, alphabetListOrdered))

  alphabetListShuffled = list(alphabetListOrdered)

  def seed():
    return seedKey

  random.shuffle(alphabetListShuffled, seed)

  numberListShuffled = list(map(ord, alphabetListShuffled))

  return convertAlphabets(list(map(ord, list(m))), numberListOrdered, numberListShuffled, False)



m = "Vous savez, moi je ne crois pas qu'il y ait de bonne ou de mauvaise situation. Moi, si je devais resumer ma vie aujourd'hui avec vous, je dirais que c'est d'abord des rencontres. Des gens qui m'ont tendu la main, peut-etre a un moment ou je ne pouvais pas, ou j'etais seul chez moi"
m
e = encryptMessageRand(m, 0.42)
e
d = decryptMessageRand(e, 0.42)
d<jupyter_output><ipython-input-17-6c852534887f>:14: DeprecationWarning: The *random* parameter to shuffle() has been deprecated
since Python 3.9 and will be removed in a subsequent version.
  random.shuffle(alphabetListShuffled, seed)<jupyter_text>Cracking a Random Cypher Voici un cypher généré avec l'algorithme d'encryption de cypher encryptMessageRand.Le but est d'arriver a decrypter le message grace a l'analyse de frequence des caracteres du message. Le message code est en anglais, donc un morceau de texte anglais vous est donne pour que vous puissez comparer les frequences.<jupyter_code>random_cypher = 'J \t _ n \t i _ q q z \t u p \t k p j 2 \t x j u i \t z p v \t u p e _ z \t j 2 \t x i _ u \t x j m m \t h p \t e p x 2 \t j 2 \t i j t u p s z \t _ t \t u i f \t h s f _ u f t u \t e f n p 2 t u s _ u j p 2 \t 1 p s \t 1 s f f e p n \t j 2 \t u i f \t i j t u p s z \t p 1 \t p v s \t 2 _ u j p 2 / \t G j 3 f \t t d p s f \t z f _ s t \t _ h p - \t _ \t h s f _ u \t B n f s j d _ 2 - \t j 2 \t x i p t f \t t z n \n p m j d \t t i _ e p x \t x f \t t u _ 2 e \t u p e _ z - \t t j h 2 f e \t u i f \t F n _ 2 d j q _ u j p 2 \t Q s p d m _ n _ u j p 2 / \t 6 i j t \t n p n f 2 u p v t \t e f d s f f \t d _ n f \t _ t \t _ \t h s f _ u \t \n f _ d p 2 \t m j h i u \t p 1 \t i p q f \t u p \t n j m m j p 2 t \t p 1 \t O f h s p \t t m _ 3 f t \t x i p \t i _ e \t \n f f 2 \t t f _ s f e \t j 2 \t u i f \t 1 m _ n f t \t p 1 \t x j u i f s j 2 h \t j 2 k v t u j d f / \t J u \t d _ n f \t _ t \t _ \t k p z p v t \t e _ z \n s f _ l \t u p \t f 2 e \t u i f \t m p 2 h \t 2 j h i u \t p 1 \t u i f j s \t d _ q u j 3 j u z / \t C v u \t p 2 f \t i v 2 e s f e \t z f _ s t \t m _ u f s - \t u i f \t O f h s p \t t u j m m \t j t \t 2 p u \t 1 s f f / \t P 2 f \t i v 2 e s f e \t z f _ s t \t m _ u f s - \t u i f \t m j 1 f \t p 1 \t u i f \t O f h s p \t j t \t t u j m m \t t _ e m z \t d s j q q m f e \t \n z \t u i f \t n _ 2 _ d m f t \t p 1 \t t f h s f h _ u j p 2 \t _ 2 e \t u i f \t d i _ j 2 t \t p 1 \t e j t d s j n j 2 _ u j p 2 / \t P 2 f \t i v 2 e s f e \t z f _ s t \t m _ u f s - \t u i f \t O f h s p \t m j 3 f t \t p 2 \t _ \t m p 2 f m z \t j t m _ 2 e \t p 1 \t q p 3 f s u z \t j 2 \t u i f \t n j e t u \t p 1 \t _ \t 3 _ t u \t p d f _ 2 \t p 1 \t n _ u f s j _ m \t q s p t q f s j u z / \t P 2 f \t i v 2 e s f e \t z f _ s t \t m _ u f s - \t u i f \t O f h s p \t j t \t t u j m m \t m _ 2 h v j t i f e \t j 2 \t u i f \t d p s 2 f s t \t p 1 \t B n f s j d _ 2 \t t p d j f u z \t _ 2 e \t 1 j 2 e t \t i j n t f m 1 \t _ 2 \t f y j m f \t j 2 \t i j t \t p x 2 \t m _ 2 e / \t B 2 e \t t p \t x f ( 3 f \t d p n f \t i f s f \t u p e _ z \t u p \t e s _ n _ u j A f \t _ \t t i _ n f 1 v m \t d p 2 e j u j p 2 /'

random_cypherList = list(random_cypher)[0::2]
random_cypherList
englishText = "I am the First Accused.I hold a Bachelor's Degree in Arts and practised as an attorney in Johannesburg for a number of years in partnership with <NAME>. I am a convicted prisoner serving five years for leaving the country without a permit and for inciting people to go on strike at the end of May 1961. At the outset, I want to say that the suggestion made by the State in its opening that the struggle in South Africa is under the influence of foreigners or communists is wholly incorrect. I have done whatever I did, both as an individual and as a leader of my people, because of my experience in South Africa and my own proudly felt African background, and not because of what any outsider might have said. In my youth in the Transkei I listened to the elders of my tribe telling stories of the old days. Amongst the tales they related to me were those of wars fought by our ancestors in defence of the fatherland. The names of Dingane and Bambata, Hintsa and Makana, Squngthi and Dalasile, Moshoeshoe and Sekhukhuni, were praised as the glory of the entire African nation. I hoped then that life might offer me the opportunity to serve my people and make my own humble contribution to their freedom struggle. This is what has motivated me in all that I have done in relation to the charges made against me in this case. Having said this, I must deal immediately and at some length with the question of violence. Some of the things so far told to the Court are true and some are untrue. I do not, however, deny that I planned sabotage. I did not plan it in a spirit of recklessness, nor because I have any love of violence. I planned it as a result of a calm and sober assessment of the political situation that had arisen after many years of tyranny, exploitation, and oppression of my people by the Whites."<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.0606171484327357, 'fraction_numerical': 0.02323454079765825, 'mean_word_length': 2.695132942767012, 'pattern_counts': {'":': 0, '<': 46, '<?xml version=': 0, '>': 43, 'https://': 1, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 242, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '3274', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 6437, 'n_tokens_neox': 5990, 'n_words': 3705, 'path': 'Exercises/Hands_on_Cypher/Hands_on_Cypher.ipynb', 'repo_name': 'AGuyNextDoor/AProfNextDoor', 'size': '16416'}