From 3e4fa941394bc031be3cc2032f3d8fe08f20318b Mon Sep 17 00:00:00 2001 From: anperederi Date: Mon, 12 Feb 2024 18:50:24 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=9D=20Add=20tp3=20of=20cryptography?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Untitled-checkpoint.ipynb | 414 ++++++++++++++++++ 2A/Cryptographie/tp/tp3/Untitled.ipynb | 414 ++++++++++++++++++ 2 files changed, 828 insertions(+) create mode 100644 2A/Cryptographie/tp/tp3/.ipynb_checkpoints/Untitled-checkpoint.ipynb create mode 100644 2A/Cryptographie/tp/tp3/Untitled.ipynb diff --git a/2A/Cryptographie/tp/tp3/.ipynb_checkpoints/Untitled-checkpoint.ipynb b/2A/Cryptographie/tp/tp3/.ipynb_checkpoints/Untitled-checkpoint.ipynb new file mode 100644 index 0000000..dbfda88 --- /dev/null +++ b/2A/Cryptographie/tp/tp3/.ipynb_checkpoints/Untitled-checkpoint.ipynb @@ -0,0 +1,414 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e4a99103-1fbd-43a9-9464-bb220e226097", + "metadata": {}, + "source": [ + "# TP 3 : Chiffrement asymétrique El Gamal\n", + "## Chiffrement d’El Gamal\n", + "Le chiffrement d’El Gamal est un protocole de cryptographie asymétrique inventé par Taher El Gamal\n", + "en 1984 et qui repose sur le problème du logarithme discret.\n", + "## Génération des clefs.\n", + "La première étape du schéma de chiffrement consiste à produire une paire de clefs : la clef publique,\n", + "et la clef secrète (ou clé privée). La première servira à chiffrer les messages et la deuxième à les\n", + "déchiffrer.\n", + "Pour générer sa paire de clefs, il faut d’abord choisir un nombre premier p et un générateur g pour\n", + "Z/pZ.\n", + "Ensuite il faut choisir un élément s de Z/pZ qui constituera la clef privée, et calculer h = g\n", + "s mod p.\n", + "Pour terminer, la clé publique est (p, g, h).\n", + "## Chiffrement\n", + "Pour chiffrer un message M encodé comme un entier de Z/pZ avec la clé publique (p, g, h), il faut\n", + "tirer au hasard un aléa r dans Z/pZ et calculer C1 = g\n", + "r mod p et C2 = (M ·(h\n", + "r mod p)) mod p.\n", + "Ainsi le chiffré C est composé de ces deux nombres : C = (C1, C2).\n", + "## Déchiffrement\n", + "Ayant accès à C = (C1, C2) et à la clé privée s, pour déchiffrer il suffit de calculer :\n", + "\u0010\n", + "C2 × ((C1)\n", + "s mod p)\n", + "−1 mod p\n", + "\u0011\n", + "mod p\n", + "pour retrouver le message M" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "id": "c5b14247-bb01-4d53-bfe9-a6794e1d083a", + "metadata": {}, + "outputs": [], + "source": [ + "from sympy import randprime\n", + "from sympy import mod_inverse\n", + "from random import randint" + ] + }, + { + "cell_type": "markdown", + "id": "da5acb5b-c88f-4cf8-b77f-5730a2fb8b8b", + "metadata": {}, + "source": [ + "# Exercice 1" + ] + }, + { + "cell_type": "markdown", + "id": "cb40eddd-9d83-4866-a2fb-596c936b6c96", + "metadata": {}, + "source": [ + "## (Génération des clefs). \n", + "Écrivez une fonction Python3 Clefs(k) qui permet de générer\n", + "une paire de clefs El Gamal, avec un module compris entre 2k et 2k+1 − 1.\n", + "La taille compte ! Plus vos clés seront de grands nombres, plus elles seront sûres. Le « paramètre de\n", + "sécurité » est donc le nombre de bits du module p, autrement dit son logarithme binaire k.\n", + "Vous aurez peut-être l’usage de la fonction randprime de la bibliothèque sympy (éventuellement à\n", + "installer en tapant pip install sympy dans un terminal) et de la fonction randint de la bibliothèque random. Pour calculer x\n", + "n mod p vous devrez utiliser pow(x, n, mod=p) car (x**n)%p ne\n", + "marche pas pour les grands nombres. Attention, ce n’est pas une fonction de la bibliothèque math ! !\n", + "### 1. Choisissez comme module un nombre premier p au hasard compris entre 2k et 2k+1 − 1.\n", + "### 2. Choisissez comme générateur un nombre g au hasard compris entre 2 et p − 1.\n", + "Remarque : Votre « générateur » n’en est peut-être pas un. Pour gagner du temps, on ne\n", + "vous demande pas de le vérifier : la procédure de chiffrement/déchiffrement marche encore,\n", + "mais votre clé sera plus facile à casser, car il y aura plusieurs valeurs possibles pour s, en plus\n", + "de celle qui sera vraiment votre clé secrète.\n", + "### 3. Choisissez comme secret un nombre s au hasard compris entre 2 et p − 1.\n", + "### 4. Calculez h." + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "fc076bdc-53b4-4c7a-947e-93545a63cb81", + "metadata": {}, + "outputs": [], + "source": [ + "def Clef(k):\n", + " p = randprime(2**k, 2**(k+1) - 1)\n", + " g = randint(2, p)\n", + " s = randint(2, p)\n", + " h = pow(g, s, mod=p)\n", + " return (p, g, h), s" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "ccddb73a-53f9-45dc-9d0f-12ea0b7bc880", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "((59, 59, 0), 2)\n" + ] + } + ], + "source": [ + "print(Clef(5))" + ] + }, + { + "cell_type": "markdown", + "id": "dca8a06b-a782-42ef-ac24-bb7b448b2d39", + "metadata": {}, + "source": [ + "# Exercice 2. \n", + "## Écrivez une fonction Python3 Chiffrer(...) qui permet de chiffrer un nombre M avec le chiffrement d’El Gamal." + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "9bcdf40f-6aa0-47f3-aee7-efcd5b6bf1a5", + "metadata": {}, + "outputs": [], + "source": [ + "def Chiffrer(M, p, g, h):\n", + " r = randint(0, p)\n", + " C1 = pow(g, r, mod=p)\n", + " C2 = (M * pow(h, r, mod=p))%p\n", + " return C1, C2" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "id": "e5abbe34-905f-4651-8744-952376af16b2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Génération de clef : \n", + "Clef public : (1871, 1240, 1473)\n", + "Clef privé : 1063\n", + "Chiffrement de 1200 Soit un chiffré c = (973, 292)\n" + ] + } + ], + "source": [ + "print(\"Génération de clef : \")\n", + "public, prive = Clef(10)\n", + "print(\"Clef public : \", public)\n", + "print(\"Clef privé : \", prive)\n", + "M = 1200\n", + "C = Chiffrer(M, public[0], public[1], public[2])\n", + "print(\"Chiffrement de \", M, \"Soit un chiffré c = \", C)" + ] + }, + { + "cell_type": "markdown", + "id": "606ffacb-eb0d-4023-8c5f-86a885f5fc3f", + "metadata": {}, + "source": [ + "# Exercice 3. \n", + "## Écrivez une fonction Python3 Dechiffrer(...) qui permet de déchiffrer un chiffré (C1, C2) avec le chiffrement d’El Gamal.\n", + "Vous pouvez calculer l’inverse de x modulo p (s’il existe) par pow(x, -1, p)." + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "id": "1827a062-4875-411e-820b-6c040bd42a9f", + "metadata": {}, + "outputs": [], + "source": [ + "def Dechiffrer(C1, C2, s, p):\n", + " M = (C2 * mod_inverse(pow(C1, s, mod=p), p))%p\n", + " return M" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "id": "9d49814a-be2f-4875-815d-296d08e74a1c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Message à déchiffrer : (973, 292)\n", + "Resultat après déchiffrement : 1200\n" + ] + } + ], + "source": [ + "print(\"Message à déchiffrer : \", C)\n", + "Md = Dechiffrer(C[0], C[1], prive, public[0])\n", + "print(\"Resultat après déchiffrement : \", Md)" + ] + }, + { + "cell_type": "markdown", + "id": "ca4ddadd-1181-4b1d-a6a8-f50f4c53dc84", + "metadata": {}, + "source": [ + "# Exercice 4. \n", + "Fondamentalement, le chiffrement d’El Gamal s’applique à des nombres. Mais très souvent, les messages qu’on souhaite chiffrer sont plutôt des textes ! Pour chiffrer des textes, il faut donc passer par une étape préalable de numérisation des caractères qui le composent.\n", + "### 1. Écrivez une fonction Python3 Encode(texte) qui convertit une chaîne de caractères texte en un nombre entier. Il y a plusieurs manières de faire cela, voici celle que nous proposons ici :\n", + "(a) Chaque caractère est encodé par son code ASCII décimal, composé de 1, 2 ou 3 chiffres. Étant donné un caractère c, le code ASCII correspondant est obtenu par ord(c). \n", + "(b) Les codes ASCII des caractères sont transformés en str, puis ramenés sur 3 chiffres en ajoutant si nécessaire des 0 à gauche. \n", + "(c) Les chaînes représentant les codes ASCII sur 3 chiffres sont concaténées les unes à la suite des autres pour obtenir une seule (grande) chaîne, ensuite transformée en int. \n", + "### 2. Écrivez une fonction Python3 Decode(nombre) effectuant l’opération réciproque : étant donné un nombre entier nombre, retrouver la chaîne de caractères texte qu’il représente.\n", + "Pour cela, utilisez la fonction chr. Étant un code ASCII donné num, le caractère associé est\n", + "obtenu par chr(num).\n", + "Pour récupérer les codes ASCII des différents caractères, vous voudrez peut-être utiliser le\n", + "reste (%) et le quotient (//) de la division par 1000.\n", + "### 3. Testez vos fonctions d’encodage/décodage. On doit avoir, pour tout message M :\n", + "M=Decode(Encode(M))" + ] + }, + { + "cell_type": "code", + "execution_count": 171, + "id": "bcbf166a-3b1f-4610-91ad-f34c4489e53f", + "metadata": {}, + "outputs": [], + "source": [ + "def Encode(texte):\n", + " newTexte = \"\"\n", + " for i in range(len(texte)):\n", + " newTexte = newTexte + str(ord(texte[i])).zfill(3)\n", + " intTexte = int(newTexte)\n", + " return intTexte" + ] + }, + { + "cell_type": "code", + "execution_count": 168, + "id": "6aac494a-7bae-4bff-a054-9e8832bde008", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "69115115097105" + ] + }, + "execution_count": 168, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Encode(\"Essai\")" + ] + }, + { + "cell_type": "code", + "execution_count": 184, + "id": "4986d5be-89c1-441c-8cfc-87e265998d16", + "metadata": {}, + "outputs": [], + "source": [ + "def Decode(nb):\n", + " res = \"\"\n", + " while nb > 0 :\n", + " res = chr(nb % 1000) + res\n", + " nb = nb // 1000\n", + " return res" + ] + }, + { + "cell_type": "code", + "execution_count": 185, + "id": "30aa336c-5959-49d6-90b1-b57b5ed9fa92", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Essai'" + ] + }, + "execution_count": 185, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Decode(69115115097105)" + ] + }, + { + "cell_type": "code", + "execution_count": 179, + "id": "9f2678f3-8180-46c9-aba0-f9a975775a12", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(1443295143187065358570471830895, 895427499536852088675129942696)" + ] + }, + "execution_count": 179, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Chiffrer(Encode(\"Yoloyolo boys\"), 2300342751692871968900072455807, 1945803074531676481815246424499, 150618869292435473863944805702)" + ] + }, + { + "cell_type": "markdown", + "id": "e02cb23c-4b07-4d2f-a086-693fa11c5245", + "metadata": {}, + "source": [ + "# Exercice 7 \n", + "(Exponentielle).\n", + "### 1. Écrire une fonction exp_basique(x,n,p) qui, pour trois entiers positifs x, n, p donnés en entrée, calcule de manière basique (sans utiliser la bibliothèque math) l’exponentielle modulaire x n mod p\n", + "### 2. L’algorithme d’exponentielle rapide permet également de calculer le nombre x n mod p mais en utilisant l’algorithme récursif suivant :\n", + "puissance(x, n) =\n", + "\n", + "\n", + "\n", + "x, si n = 1\n", + "puissance(x\n", + "2\n", + ", n/2), si n est pair\n", + "x × puissance(x\n", + "2\n", + ", (n − 1)/2), si n est impair \n", + "Écrire une fonction exp_rapide(x,n,p) implémentant cet algorithme.\n", + "### 3. Calculer le nombre suivant, avec les deux méthodes :\n", + "123456789123456789 (mod 987654321) = 598987215\n", + "Que constatez-vous ?" + ] + }, + { + "cell_type": "code", + "execution_count": 188, + "id": "5e226a8c-c067-4f5e-8ab6-3e698d540a7d", + "metadata": {}, + "outputs": [], + "source": [ + "def exp_basique(x, n, p):\n", + " return (x**n)%p" + ] + }, + { + "cell_type": "code", + "execution_count": 192, + "id": "7bf34597-1e83-4ba2-9a79-5d0b95aac962", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3\n", + "3\n" + ] + } + ], + "source": [ + "print(exp_basique(973, 2, 1871))\n", + "print(pow(973, 2, 1871))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "74960463-b5c5-4bc2-951e-4f4de37a93a8", + "metadata": {}, + "outputs": [], + "source": [ + "def exp_rapide(x, n, p):\n", + " if(n = 1):\n", + " return x\n", + " if(n%2 = 0):\n", + " return puissance(x, n, p)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/2A/Cryptographie/tp/tp3/Untitled.ipynb b/2A/Cryptographie/tp/tp3/Untitled.ipynb new file mode 100644 index 0000000..dbfda88 --- /dev/null +++ b/2A/Cryptographie/tp/tp3/Untitled.ipynb @@ -0,0 +1,414 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e4a99103-1fbd-43a9-9464-bb220e226097", + "metadata": {}, + "source": [ + "# TP 3 : Chiffrement asymétrique El Gamal\n", + "## Chiffrement d’El Gamal\n", + "Le chiffrement d’El Gamal est un protocole de cryptographie asymétrique inventé par Taher El Gamal\n", + "en 1984 et qui repose sur le problème du logarithme discret.\n", + "## Génération des clefs.\n", + "La première étape du schéma de chiffrement consiste à produire une paire de clefs : la clef publique,\n", + "et la clef secrète (ou clé privée). La première servira à chiffrer les messages et la deuxième à les\n", + "déchiffrer.\n", + "Pour générer sa paire de clefs, il faut d’abord choisir un nombre premier p et un générateur g pour\n", + "Z/pZ.\n", + "Ensuite il faut choisir un élément s de Z/pZ qui constituera la clef privée, et calculer h = g\n", + "s mod p.\n", + "Pour terminer, la clé publique est (p, g, h).\n", + "## Chiffrement\n", + "Pour chiffrer un message M encodé comme un entier de Z/pZ avec la clé publique (p, g, h), il faut\n", + "tirer au hasard un aléa r dans Z/pZ et calculer C1 = g\n", + "r mod p et C2 = (M ·(h\n", + "r mod p)) mod p.\n", + "Ainsi le chiffré C est composé de ces deux nombres : C = (C1, C2).\n", + "## Déchiffrement\n", + "Ayant accès à C = (C1, C2) et à la clé privée s, pour déchiffrer il suffit de calculer :\n", + "\u0010\n", + "C2 × ((C1)\n", + "s mod p)\n", + "−1 mod p\n", + "\u0011\n", + "mod p\n", + "pour retrouver le message M" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "id": "c5b14247-bb01-4d53-bfe9-a6794e1d083a", + "metadata": {}, + "outputs": [], + "source": [ + "from sympy import randprime\n", + "from sympy import mod_inverse\n", + "from random import randint" + ] + }, + { + "cell_type": "markdown", + "id": "da5acb5b-c88f-4cf8-b77f-5730a2fb8b8b", + "metadata": {}, + "source": [ + "# Exercice 1" + ] + }, + { + "cell_type": "markdown", + "id": "cb40eddd-9d83-4866-a2fb-596c936b6c96", + "metadata": {}, + "source": [ + "## (Génération des clefs). \n", + "Écrivez une fonction Python3 Clefs(k) qui permet de générer\n", + "une paire de clefs El Gamal, avec un module compris entre 2k et 2k+1 − 1.\n", + "La taille compte ! Plus vos clés seront de grands nombres, plus elles seront sûres. Le « paramètre de\n", + "sécurité » est donc le nombre de bits du module p, autrement dit son logarithme binaire k.\n", + "Vous aurez peut-être l’usage de la fonction randprime de la bibliothèque sympy (éventuellement à\n", + "installer en tapant pip install sympy dans un terminal) et de la fonction randint de la bibliothèque random. Pour calculer x\n", + "n mod p vous devrez utiliser pow(x, n, mod=p) car (x**n)%p ne\n", + "marche pas pour les grands nombres. Attention, ce n’est pas une fonction de la bibliothèque math ! !\n", + "### 1. Choisissez comme module un nombre premier p au hasard compris entre 2k et 2k+1 − 1.\n", + "### 2. Choisissez comme générateur un nombre g au hasard compris entre 2 et p − 1.\n", + "Remarque : Votre « générateur » n’en est peut-être pas un. Pour gagner du temps, on ne\n", + "vous demande pas de le vérifier : la procédure de chiffrement/déchiffrement marche encore,\n", + "mais votre clé sera plus facile à casser, car il y aura plusieurs valeurs possibles pour s, en plus\n", + "de celle qui sera vraiment votre clé secrète.\n", + "### 3. Choisissez comme secret un nombre s au hasard compris entre 2 et p − 1.\n", + "### 4. Calculez h." + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "fc076bdc-53b4-4c7a-947e-93545a63cb81", + "metadata": {}, + "outputs": [], + "source": [ + "def Clef(k):\n", + " p = randprime(2**k, 2**(k+1) - 1)\n", + " g = randint(2, p)\n", + " s = randint(2, p)\n", + " h = pow(g, s, mod=p)\n", + " return (p, g, h), s" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "ccddb73a-53f9-45dc-9d0f-12ea0b7bc880", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "((59, 59, 0), 2)\n" + ] + } + ], + "source": [ + "print(Clef(5))" + ] + }, + { + "cell_type": "markdown", + "id": "dca8a06b-a782-42ef-ac24-bb7b448b2d39", + "metadata": {}, + "source": [ + "# Exercice 2. \n", + "## Écrivez une fonction Python3 Chiffrer(...) qui permet de chiffrer un nombre M avec le chiffrement d’El Gamal." + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "9bcdf40f-6aa0-47f3-aee7-efcd5b6bf1a5", + "metadata": {}, + "outputs": [], + "source": [ + "def Chiffrer(M, p, g, h):\n", + " r = randint(0, p)\n", + " C1 = pow(g, r, mod=p)\n", + " C2 = (M * pow(h, r, mod=p))%p\n", + " return C1, C2" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "id": "e5abbe34-905f-4651-8744-952376af16b2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Génération de clef : \n", + "Clef public : (1871, 1240, 1473)\n", + "Clef privé : 1063\n", + "Chiffrement de 1200 Soit un chiffré c = (973, 292)\n" + ] + } + ], + "source": [ + "print(\"Génération de clef : \")\n", + "public, prive = Clef(10)\n", + "print(\"Clef public : \", public)\n", + "print(\"Clef privé : \", prive)\n", + "M = 1200\n", + "C = Chiffrer(M, public[0], public[1], public[2])\n", + "print(\"Chiffrement de \", M, \"Soit un chiffré c = \", C)" + ] + }, + { + "cell_type": "markdown", + "id": "606ffacb-eb0d-4023-8c5f-86a885f5fc3f", + "metadata": {}, + "source": [ + "# Exercice 3. \n", + "## Écrivez une fonction Python3 Dechiffrer(...) qui permet de déchiffrer un chiffré (C1, C2) avec le chiffrement d’El Gamal.\n", + "Vous pouvez calculer l’inverse de x modulo p (s’il existe) par pow(x, -1, p)." + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "id": "1827a062-4875-411e-820b-6c040bd42a9f", + "metadata": {}, + "outputs": [], + "source": [ + "def Dechiffrer(C1, C2, s, p):\n", + " M = (C2 * mod_inverse(pow(C1, s, mod=p), p))%p\n", + " return M" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "id": "9d49814a-be2f-4875-815d-296d08e74a1c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Message à déchiffrer : (973, 292)\n", + "Resultat après déchiffrement : 1200\n" + ] + } + ], + "source": [ + "print(\"Message à déchiffrer : \", C)\n", + "Md = Dechiffrer(C[0], C[1], prive, public[0])\n", + "print(\"Resultat après déchiffrement : \", Md)" + ] + }, + { + "cell_type": "markdown", + "id": "ca4ddadd-1181-4b1d-a6a8-f50f4c53dc84", + "metadata": {}, + "source": [ + "# Exercice 4. \n", + "Fondamentalement, le chiffrement d’El Gamal s’applique à des nombres. Mais très souvent, les messages qu’on souhaite chiffrer sont plutôt des textes ! Pour chiffrer des textes, il faut donc passer par une étape préalable de numérisation des caractères qui le composent.\n", + "### 1. Écrivez une fonction Python3 Encode(texte) qui convertit une chaîne de caractères texte en un nombre entier. Il y a plusieurs manières de faire cela, voici celle que nous proposons ici :\n", + "(a) Chaque caractère est encodé par son code ASCII décimal, composé de 1, 2 ou 3 chiffres. Étant donné un caractère c, le code ASCII correspondant est obtenu par ord(c). \n", + "(b) Les codes ASCII des caractères sont transformés en str, puis ramenés sur 3 chiffres en ajoutant si nécessaire des 0 à gauche. \n", + "(c) Les chaînes représentant les codes ASCII sur 3 chiffres sont concaténées les unes à la suite des autres pour obtenir une seule (grande) chaîne, ensuite transformée en int. \n", + "### 2. Écrivez une fonction Python3 Decode(nombre) effectuant l’opération réciproque : étant donné un nombre entier nombre, retrouver la chaîne de caractères texte qu’il représente.\n", + "Pour cela, utilisez la fonction chr. Étant un code ASCII donné num, le caractère associé est\n", + "obtenu par chr(num).\n", + "Pour récupérer les codes ASCII des différents caractères, vous voudrez peut-être utiliser le\n", + "reste (%) et le quotient (//) de la division par 1000.\n", + "### 3. Testez vos fonctions d’encodage/décodage. On doit avoir, pour tout message M :\n", + "M=Decode(Encode(M))" + ] + }, + { + "cell_type": "code", + "execution_count": 171, + "id": "bcbf166a-3b1f-4610-91ad-f34c4489e53f", + "metadata": {}, + "outputs": [], + "source": [ + "def Encode(texte):\n", + " newTexte = \"\"\n", + " for i in range(len(texte)):\n", + " newTexte = newTexte + str(ord(texte[i])).zfill(3)\n", + " intTexte = int(newTexte)\n", + " return intTexte" + ] + }, + { + "cell_type": "code", + "execution_count": 168, + "id": "6aac494a-7bae-4bff-a054-9e8832bde008", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "69115115097105" + ] + }, + "execution_count": 168, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Encode(\"Essai\")" + ] + }, + { + "cell_type": "code", + "execution_count": 184, + "id": "4986d5be-89c1-441c-8cfc-87e265998d16", + "metadata": {}, + "outputs": [], + "source": [ + "def Decode(nb):\n", + " res = \"\"\n", + " while nb > 0 :\n", + " res = chr(nb % 1000) + res\n", + " nb = nb // 1000\n", + " return res" + ] + }, + { + "cell_type": "code", + "execution_count": 185, + "id": "30aa336c-5959-49d6-90b1-b57b5ed9fa92", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Essai'" + ] + }, + "execution_count": 185, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Decode(69115115097105)" + ] + }, + { + "cell_type": "code", + "execution_count": 179, + "id": "9f2678f3-8180-46c9-aba0-f9a975775a12", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(1443295143187065358570471830895, 895427499536852088675129942696)" + ] + }, + "execution_count": 179, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Chiffrer(Encode(\"Yoloyolo boys\"), 2300342751692871968900072455807, 1945803074531676481815246424499, 150618869292435473863944805702)" + ] + }, + { + "cell_type": "markdown", + "id": "e02cb23c-4b07-4d2f-a086-693fa11c5245", + "metadata": {}, + "source": [ + "# Exercice 7 \n", + "(Exponentielle).\n", + "### 1. Écrire une fonction exp_basique(x,n,p) qui, pour trois entiers positifs x, n, p donnés en entrée, calcule de manière basique (sans utiliser la bibliothèque math) l’exponentielle modulaire x n mod p\n", + "### 2. L’algorithme d’exponentielle rapide permet également de calculer le nombre x n mod p mais en utilisant l’algorithme récursif suivant :\n", + "puissance(x, n) =\n", + "\n", + "\n", + "\n", + "x, si n = 1\n", + "puissance(x\n", + "2\n", + ", n/2), si n est pair\n", + "x × puissance(x\n", + "2\n", + ", (n − 1)/2), si n est impair \n", + "Écrire une fonction exp_rapide(x,n,p) implémentant cet algorithme.\n", + "### 3. Calculer le nombre suivant, avec les deux méthodes :\n", + "123456789123456789 (mod 987654321) = 598987215\n", + "Que constatez-vous ?" + ] + }, + { + "cell_type": "code", + "execution_count": 188, + "id": "5e226a8c-c067-4f5e-8ab6-3e698d540a7d", + "metadata": {}, + "outputs": [], + "source": [ + "def exp_basique(x, n, p):\n", + " return (x**n)%p" + ] + }, + { + "cell_type": "code", + "execution_count": 192, + "id": "7bf34597-1e83-4ba2-9a79-5d0b95aac962", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3\n", + "3\n" + ] + } + ], + "source": [ + "print(exp_basique(973, 2, 1871))\n", + "print(pow(973, 2, 1871))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "74960463-b5c5-4bc2-951e-4f4de37a93a8", + "metadata": {}, + "outputs": [], + "source": [ + "def exp_rapide(x, n, p):\n", + " if(n = 1):\n", + " return x\n", + " if(n%2 = 0):\n", + " return puissance(x, n, p)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}