{"id":5576,"date":"2016-10-28T17:43:20","date_gmt":"2016-10-28T15:43:20","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/?p=5576"},"modified":"2016-10-30T07:44:43","modified_gmt":"2016-10-30T06:44:43","slug":"i1m2016-el-cifrado-cesar-en-haskell","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/i1m2016-el-cifrado-cesar-en-haskell\/","title":{"rendered":"I1M2016: El cifrado C\u00e9sar en Haskell"},"content":{"rendered":"<p>En la primera parte de la clase de hoy de <a href=\"http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m-16\">Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas<\/a> hemos estudiado c\u00f3mo definir en Haskell la codificaci\u00f3n de mensajes usando el <a href=\"http:\/\/es.wikipedia.org\/wiki\/Cifrado_C\u00e9sar\">cifrado C\u00e9sar<\/a>.<\/p>\n<p>El programa es el siguiente<br \/>\n<!--more--><\/p>\n<pre lang=\"haskell\">\nimport Data.Char\n\n-- ---------------------------------------------------------------------\n-- Codificaci\u00f3n y descodificaci\u00f3n                                     --\n-- ---------------------------------------------------------------------\n\n-- (let2int c) es el entero correspondiente a la letra min\u00fascula c. Por\n-- ejemplo, \n--    let2int 'a'  ==>  0\n--    let2int 'd'  ==>  3\n--    let2int 'z'  ==>  25\nlet2int :: Char -> Int\nlet2int c = ord c - ord 'a'\n\n-- (int2let n) es la letra min\u00fascula correspondiente al entero n. Por\n-- ejemplo, \n--    int2let 0   ==>  'a'\n--    int2let 3   ==>  'd'\n--    int2let 25  ==>  'z'\nint2let :: Int -> Char\nint2let n = chr (ord 'a' + n)\n\n-- (desplaza n c) es el car\u00e1cter obtenido desplazando n caracteres el\n-- car\u00e1cter c. Por ejemplo,\n--    desplaza   3  'a'  ==>  'd'\n--    desplaza   3  'y'  ==>  'b'\n--    desplaza (-3) 'd'  ==>  'a'\n--    desplaza (-3) 'b'  ==>  'y'\ndesplaza :: Int -> Char -> Char\ndesplaza n c | isLower c = int2let ((let2int c + n) `mod` 26)\n             | otherwise =  c\n\n-- (codifica n xs) es el resultado de codificar el texto xs con un\n-- desplazamiento n. Por ejemplo,\n--    codifica   3  \"En todo la medida\"   ==>  \"Eq wrgr od phglgd\"\n--    codifica (-3) \"Eq wrgr od phglgd\"   ==>  \"En todo la medida\"\ncodifica :: Int -> String -> String\ncodifica n xs = [desplaza n x | x <- xs]\n\n-- ---------------------------------------------------------------------\n-- An\u00e1lisis de frecuencia                                             --\n-- ---------------------------------------------------------------------\n\n-- tabla es la lista de la frecuencias de las letras en castellano, Por\n-- ejemplo, la frecuencia de la 'a' es del 12.53%, la de la 'b' es 1.42%.\ntabla :: [Float]\ntabla = [12.53, 1.42, 4.68, 5.86, 13.68, 0.69, 1.01, 0.70, 6.25, \n          0.44, 0.01, 4.97, 3.15,  6.71, 8.68, 2.51, 0.88, 6.87, \n          7.98, 4.63, 3.93, 0.90,  0.02, 0.22, 0.90, 0.52]\n\n-- (minusculas xs) es la lista de min\u00fasculas en la cadena xs. Por\n-- ejemplo,\n--    minusculas \"EstoEsUnaPrueba\"  ==>  \"stosnarueba\"  \nminusculas :: String -> String\nminusculas xs = [x | x <- xs, isLower x]\n\n-- (ocurrencias x xs) es el n\u00famero de veces que ocurre el car\u00e1cter x en\n-- la cadena xs. Por ejemplo, \n--    ocurrencias 'a' \"Salamanca\"  ==>  4  \nocurrencias :: Char -> String -> Int\nocurrencias x xs = length [x1 | x1 <- xs, x == x1]\n\n-- (porcentaje n m) es el porcentaje de n sobre m. Por ejemplo,\n--    porcentaje 2 5  ==>  40.0\nporcentaje :: Int -> Int -> Float\nporcentaje n m = (fromIntegral n \/ fromIntegral m) * 100\n\n-- (frecuencias xs) es la frecuencia de cada una de las min\u00fasculas de la\n-- cadena xs. Por ejemplo, \n--    > frecuencias \"en todo la medida\"\n--    [14.3,0,0,21.4,14.3,0,0,0,7.1,0,0,7.1,\n--     7.1,7.1,14.3,0,0,0,0,7.1,0,0,0,0,0,0]\nfrecuencias :: String -> [Float]\nfrecuencias xs = \n    [porcentaje (ocurrencias x xs) n | x <- ['a'..'z']]\n    where n = length (minusculas xs)\n\n-- (chiCuadrado os es) es la medida chi cuadrado de la discrepancia\n-- entre la distribuci\u00f3n observada os y la esperada es. Por ejemplo,\n--    chiCuadrado [3,5,6] [3,5,6]  ==>  0.0\n--    chiCuadrado [3,5,6] [5,6,3]  ==>  3.9666667\nchiCuadrado :: [Float] -> [Float] -> Float\nchiCuadrado os es = sum [((o - e) ^ 2) \/ e | (o,e) <- zip os es]\n\n-- (rota n xs) es la lista obtenida rotando n posiciones los elementos\n-- de la lista xs. Por ejemplo,\n--    rota 2 \"ramo\"  ==>  \"mora\"\nrota :: Int -> [a] -> [a]\nrota n xs = drop n xs ++ take n xs\n\n-- (posiciones x xs) es la lista de las posiciones de x en la lista\n-- xs. Por ejemplo, \n--    posiciones 'a' \"Salamanca\"  ==>  [1,3,5,8]\nposiciones :: Eq a => a -> [a] -> [Int]\nposiciones x xs = [i | (x1,i) <- zip xs [0..], x == x1]\n\n-- (descifra xs) es la cadena obtenida descodificando la cadena xs por\n-- el desplazamiento que produce una distribuci\u00f3n de min\u00fasculas con\n-- la menor deviaci\u00f3n chi cuadrado respecto de la tabla de distribuci\u00f3n\n-- de las vocales en castellano. Por ejemplo, \n--   > descifra \"Lt htruqnhfit ij qf anif jx ijxhzgwnw qt xnruqj vzj jx\"\n--   \"Lo complicado de la vida es descubrir lo simple que es\"\ndescifra :: String -> String\ndescifra xs =  codifica (-factor) xs\n    where\n      factor = head (posiciones (minimum tabChi) tabChi)\n      tabChi = [chiCuadrado (rota n tabla1) tabla | n <- [0..25]]\n      tabla1 = frecuencias xs\n<\/pre>\n<p>Los apuntes correspondientes a la clase son<br \/>\n\n<!-- iframe plugin v.5.0 wordpress.org\/plugins\/iframe\/ -->\n<iframe loading=\"lazy\" src=\"http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m\/temas\/tema-5.html#cifrado-c%C3%A9sar\" width=\"100%\" frameborder=\"1\" height=\"500\" scrolling=\"yes\" class=\"iframe-class\"><\/iframe>\n<\/p>\n","protected":false},"excerpt":{"rendered":"<p>En la primera parte de la clase de hoy de Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas hemos estudiado c\u00f3mo definir en Haskell la codificaci\u00f3n de mensajes usando el cifrado C\u00e9sar. El programa es el siguiente<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"footnotes":"","_jetpack_memberships_contains_paid_content":false},"categories":[260],"tags":[270,313],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":false,"_links":{"self":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/5576"}],"collection":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/comments?post=5576"}],"version-history":[{"count":1,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/5576\/revisions"}],"predecessor-version":[{"id":5577,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/5576\/revisions\/5577"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/media?parent=5576"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/categories?post=5576"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/tags?post=5576"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}