Pour éviter que vous ne sombriez dans l'ennui d'ici janvier, voici un petit travail à effectuer pour la fin de la semaine 2 de l'année 2014.
Il s'agit de fabriquer un petit outil cryptant des chaînes de caractères en utilisant le chiffrement de Hill. Renseignez-vous sur cette méthode mise au point dans les années 1920.
Nous travaillerons sur les 95 caractères affichables du code ascii 7 bits.
Vous pourrez utiliser le fichier ci-dessous comme squelette de départ.
Vous devrez par exemple obtenir :
Haskell
*Matrix> codeHill "Rendez-vous 02:34 pm Pont de Remagen avec les microfilms" cleHill "+=rQmQEoM{hqL/0#Ksy-j1kA?Nh7}<6XJigQ{?P6D^Kv=Y5};{ Td[zXp"
avec comme clé [[12 , 22 , 1] , [2 , 24 , 1] , [12 , 7 , 3]].
Cela doit marcher dans les deux sens :
Haskell
*Matrix> ???? "+=rQmQEoM{hqL/0#Ksy-j1kA?Nh7}<6XJigQ{?P6D^Kv=Y5};{ Td[zXp" ???? "Rendez-vous 02:34 pm Pont de Remagen avec les microfilms "
Mystérieux n'est-ce pas ? Cela donne un peu de piquant à la chose. Bonne enquête...
Haskell
-- -- Anneau des classes modulo un entier -- data Classe = Integer :% Integer representant :: Classe -> Integer representant (a :% n) = a modulo :: Classe -> Integer modulo (a :% n) = n -- cas d'égalité instance Eq Classe where (a:%n) == (b:%m) = (mod a n == mod b m) && (n == m) -- affichage sous la forme a%n instance Show Classe where show (a:%n) = (show (mod a n)) ++ "%" ++ (show n) -- opérateur infixe : a%n = a modulo n infixr 9 %% (%%) :: Integer -> Integer -> Classe (%%) a n = (mod a n) :% n -- somme induite plusMod :: Integer -> Classe -> Classe -> Classe plusMod n (a :% p) (b :% m) = if (n == p) && (n == m) then (a + b) %% n else error "Classes incompatibles" -- produit induit mulMod :: Integer -> Classe -> Classe -> Classe mulMod n (a :% p) (b :% m) = if (n == p) && (n == m) then (a * b) %% n else error "Classes incompatibles" -- euclide étendu euclide :: Integer -> Integer -> (Integer,Integer,Integer) euclide a b = euc 1 0 a 0 a b where euc u v r u' v' r' |r' == 0 = (u,v,r) |otherwise = euc u' v' r' (u - q * u') (v - q * v') (r - q * r') where q = quot r r' -- inverse modulaire invMod :: Classe -> Classe invMod a = let (u,v,r) = euclide (representant a) (modulo a) in if r == 1 then (u %% (modulo a)) else error "Classe non inversible" -- -- Z / 95Z -- data Z95 = Z95 Classe deriving (Eq) z95 n = Z95 (n :% 95) instance Num Z95 where (+) (Z95 a) (Z95 b) = ???? (*) (Z95 a) (Z95 b) = ???? fromInteger n = ???? negate (Z95 x) = ???? instance Fractional Z95 where (/) c1 c2 = ???? -- Chiffrement de Hill -- Un exemple de clé sous forme d'une liste de listes d'entiers cleHill :: [[Integer]] cleHill = [[12 , 22 , 1] , [2 , 24 , 1] , [12 , 7 , 3]] -- La clé comme matrice à coefficients dans Z/95Z matHill :: [[Integer]] -> Matrice Z95 matHill cle = ????? -- Inverse de la clé comme matrice à coefficients dans Z/95Z dematHill :: [[Integer]] -> Matrice Z95 dematHill cle = ????? -- Inverse de la clé sous forme d'une double liste d'entiers invCle :: [[Integer]] -> [[Integer]] invCle cle = ????? {- Exemple d'utilisation : *Matrix> matHill cleHill | 12%95 22%95 1%95 | | 2%95 24%95 1%95 | | 12%95 7%95 3%95 | *Matrix> dematHill cleHill | 75%95 62%95 81%95 | | 42%95 73%95 25%95 | | 77%95 25%95 93%95 | *Matrix> invCle cleHill [[75,62,81],[42,73,25],[77,25,93]] -} -- Code ascii translaté dans [|0,94|] ordHill :: Char -> Integer ordHill c = ????? -- Caractère correspondant au code ascii translaté chrHill :: Integer -> Char chrHill n = ????? -- Liste des codes translatés correspondant à une chaîne donnée codeMessage :: String -> [Integer] codeMessage m = ???? -- Chaîne correspondant à une liste de codes translatés decodeMessage :: [Integer] -> String decodeMessage liste = ???? -- On découpe une liste en liste de listes de listes de longueur n -- parPaquets 3 [1..10] -- [[[1,2,3]],[[4,5,6]],[[7,8,9]],[[10,0,0]]] parPaquets :: Int -> [Integer] -> [[[Integer]]] parPaquets n liste ????? -- liste de listes extraite d'une matrice listeMat :: Matrice t -> [[t]] listeMat (Mat m) = ???? -- Le message crypté à partir d'un message clair et d'une clé sous forme de liste de listes d'entiers codeHill :: String -> [[Integer]] -> String codeHill m cle = ?????