<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0"><id>tag:blogger.com,1999:blog-1150691805752037383</id><updated>2012-04-16T00:43:14.414+02:00</updated><category term="Personal" /><category term="Música" /><category term="Ronda" /><category term="Informática" /><category term="Religión" /><category term="Fabricación" /><category term="Cerveza" /><category term="Opinión" /><category term="Viajes" /><category term="Japonés" /><category term="Política" /><category term="Historia" /><category term="Estilos" /><category term="Otras bebidas" /><title type="text">DE CERVEZAS y otras cosas</title><subtitle type="html">Este blog está cerrado. No hay nada que ver. Por favor, desfilen ordenadamente.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://civada.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://civada.blogspot.com/search/label/Inform%C3%A1tica" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/-/Inform%C3%A1tica/-/Inform%C3%A1tica?start-index=26&amp;max-results=25" /><author><name>Delirium</name><uri>http://www.blogger.com/profile/08408043740617685786</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>30</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/informatica" /><feedburner:info uri="informatica" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:browserFriendly></feedburner:browserFriendly><entry><id>tag:blogger.com,1999:blog-1150691805752037383.post-7803348957834402106</id><published>2009-10-12T09:25:00.001+02:00</published><updated>2009-10-12T09:26:46.110+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Informática" /><title type="text">CSI XVIII: Los húngaros nombran con prefijos</title><content type="html">&lt;span style="font-size: 95%;"&gt;&lt;a title="Apetitoso y pringoso bocata de salchicha polaca inversa" href="http://www.xkcd.com/645/"&gt;&lt;img src="http://img387.imageshack.us/img387/1341/rps.png" style="float:right; margin:0 0 10px 10px;" alt="" /&gt;&lt;/a&gt;El &lt;a href="http://civada.blogspot.com/2009/09/la-ronda-16-el-nombre-de-mi-cerveza.html"&gt;reciente post&lt;/a&gt; acerca del nombre de nuestras futuras (o muy presentes) cerveceras dio paso, de forma natural, a pensar de qué modo llamaríamos a nuestros productos. Ya lo comenté en el blog de Chela: me gustan los nombres relacionados con la música y hay muchos donde elegir en las anotaciones de las partituras, en latín, italiano o nuestra lengua: &lt;i&gt;Ad Libitum&lt;/i&gt;, para la cerveza tomada a la velocidad que uno quiera. &lt;i&gt;Tornada&lt;/i&gt; (estribillo), si la cerveza es para ser tomada una y otra vez, &lt;i&gt;Ritardando&lt;/i&gt;, para tomar despacio...&lt;br /&gt;&lt;br /&gt;El nombre de las cosas es importante. Y, como la mayor parte de cosas importantes, suelen dar problemas. Y en informática, el &lt;i&gt;nombrado de variables&lt;/i&gt; puede suponer todo un reto, especialmente porque cuando se hace sin cuidado puede llevar a errores de programación, cuando no a imposibilitar que cualquier otra persona entienda el código (&lt;a href="http://civada.blogspot.com/2009/01/cmo-escribir-cdigo-inmantenible.html"&gt;código inmantenible&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Por cierto, una variable no es más que un espacio en memoria destinado a albergar, en algún momento durante la ejecución del programa, algún valor. Necesitamos darle nombres para hacer referencia a ese valor. Así que, ¿qué nombre les ponemos?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="fullpost" style="font-size: 95%;"&gt;El caso es que no vale el primero que se nos ocurra. &lt;b&gt;MaryPoppins&lt;/b&gt;, por ejemplo, no vale. Porque luego tienes que operar con estas variables y en el código te pueden aparecer cosas como:&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;PedidoOctubre = MaryPoppins[3] * OdioAMiJefe;&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;Eso es código inmantenible. Una risa, si no te fuera el trabajo en descifrarlo y entenderlo.&lt;br /&gt;&lt;br /&gt;Por ello todos debemos estar de acuerdo en que el nombre de las variables debe dar pistas acerca de qué tipo de almacén estás gastando para esa variable, qué es lo que deseas guardar en ellas o qué intención tienes al emplearla. Como llamar AldolfoHitler a tu hijo: el nombre da pistas.&lt;br /&gt;&lt;br /&gt;Las empresas serias definen una serie de reglas a la hora de escribir programas: son los &lt;i&gt;coding standards&lt;/i&gt; (o guía de estilo). Son simples convenciones para que -entre otras cosas-, con independencia de las personas que hayan pasado por la empresa, el mismo estilo perdure. Las convenciones pueden ayudar en el problema de nombrer variables, imponiendo una serie de reglas. Algunas de ellas están muy extendidas y las emplean la mayor parte de programadores en diversos lenguajes. por ejemplo, llamar &lt;b&gt;i&lt;/b&gt;, &lt;b&gt;j&lt;/b&gt;, &lt;b&gt;k&lt;/b&gt; a las variables dentro de un bucle.&lt;br /&gt;&lt;br /&gt;Una de las Cosas que Sí se estudió en Informática es la &lt;b&gt;notación húngara&lt;/b&gt;. La notación húngara fue creada por &lt;a href="http://es.wikipedia.org/wiki/Charles_Simonyi"&gt;Charles Simonyi&lt;/a&gt;, uno de los grandes programadores y reciente turista espacial&lt;a href="#fn1"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;. La notación húngara se caracteriza por anteponer al nombre de la variable un prefijo que nos da pistas acerca del &lt;i&gt;tipo de variable&lt;/i&gt; que estamos empleando. El tipo de variable es la forma del almacén que estamos gastando para guardar su valor.&lt;br /&gt;&lt;br /&gt;No voy a a explicar demasiado, porque esto da para otro post: me contentaré con poner algunos ejemplos sencillos. Una variable de tipo &lt;i&gt;carácter&lt;/i&gt; está pensada y tiene el espacio asignado para guardar un carácter. Una variable que fuera de tipo &lt;i&gt;cadena&lt;/i&gt; tendría un almacén asignado para almacenar una cadena de caracteres.&lt;br /&gt;&lt;br /&gt;Entonces, si queremos almacenar un carácter en nuestro programa para guardar la preferencia de un usuario (que lo introduce mediante el teclado), declaramos una variable llamada UserOption y si empleamos la notación húngara, lo hacemos así:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;caracter&lt;/b&gt; &lt;tt&gt;cUserOption&lt;/tt&gt;;&lt;br /&gt;&lt;br /&gt;Mediante esta linea le decimos al compilador (que es típicamente quien traduce nuestro programa a la máquina) que en algún momento tendrá que reservar un hueco en memoria para almacenar una variable de tipo &lt;b&gt;caracter&lt;/b&gt; y que se llamará &lt;b&gt;cUserOption&lt;/b&gt;. La 'c' usada como prefijo nos recuerda, cuando realizamos operaciones con esta variable, que se encuentra almacenada como un carácter.&lt;br /&gt;&lt;br /&gt;La notación húngara tiene cierto sentido cuando, al operar entre variables de distinto tipo, podemos obtener problemas o resultados indeseados. Y justamente, el hecho de que se produjeran tantos errores al operar entre variables de distintos tipos dio lugar a la creación de los &lt;b&gt;lenguajes fuertemente tipados&lt;/b&gt;, en los cuales el compilador impide realizar esta clase de operaciones. Así que la notación húngara dejó de tener sentido para muchos programadores.&lt;br /&gt;&lt;br /&gt;Otra versión de la notación húngara sugiere que el prefijo debe estar más relacionado con la función que la variable va a cumplir que con el tipo de almacenamiento. Esta versión del invento cuenta con más adeptos, ya que no ha perdido el sentido al reforzar los compiladores el análisis de tipos. Algunos ejemplos de este uso son:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;numeroentero&lt;/b&gt; &lt;tt&gt;nSandias&lt;/tt&gt;;&lt;br /&gt;&lt;br /&gt;Que informa al compilador de que debe guardar un espacio para almacenar un número entero. En ese espacio guardaremos el &lt;i&gt;número&lt;/i&gt; de sandías de nuestra aplicación. De ahí el prefijo 'n'. Pero como si no hay guía de estilo, nadie tiene por qué saber que 'n' es de 'número' en vez de 'nuevas', pues resulta que la notación húngara sigue sin ser ninguna panacea.&lt;br /&gt;&lt;br /&gt;Esta notación, sin embargo, se sigue empleando... y mucho. Porque Charles Simonyi fue fichado por Bill Gates y la notación húngara pasó a formar parte intrínseca de las aplicaciones de Microsoft, incluyendo su Sistema Operativo más popular. En los últimos tiempos, sin embargo, hasta los de Redmond se desdicen y &lt;a href="http://msdn.microsoft.com/en-us/ms229045.aspx"&gt;recomiendan no emplear&lt;/a&gt; este sistema de nombrado en el código.&lt;br /&gt;&lt;br /&gt;Recordar la notación húngara de prefijos me ha recordado otras notaciones algebraicas, que también tienen que ver mucho con la informática. Me refiero a la &lt;a href="http://es.wikipedia.org/wiki/Notaci%C3%B3n_polaca"&gt;notación polaca&lt;/a&gt; (o infija) y a la &lt;a href="http://es.wikipedia.org/wiki/Notaci%C3%B3n_polaca_inversa"&gt;polaca inversa&lt;/a&gt; (o postfija). Rápidamente:&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;(3 + 2) * 5 - Ésta es una operación como a usted a y mi nos enseñaron en el cole.&lt;br /&gt;* + 3 2 5 --- Es lo mismo que antes en notación polaca. Lo inventó &lt;a href="http://es.wikipedia.org/wiki/Jan_%C5%81ukasiewicz"&gt;un polaco&lt;/a&gt;.&lt;br /&gt;3 2 + 5 * --- Es lo mismo, pero en polaca inversa.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;De los tres, el más útil y divertido es el de polaca inversa. Útil para algunas calculadoras, claro. Polaca y polaca inversa no precisan de paréntesis, ni de conocer las reglas de precedencia (no hay expresiones ambiguas). Eso le viene muy bien al informático para realizar cálculos. En polaca inversa, cada vez que se encuentra un operador, se realiza el cálculo indicado: los operados habrán sido leídos anteriormente (o hay un error en la expresión).&lt;br /&gt;&lt;br /&gt;La polaca inversa tiene desventajas. Los espacios en las expresiones son de vital importancia para no confundir la expresión. Y como no se enseña en las escuelas ni se aplica sobre el papel, su uso está muy limitado.&lt;br /&gt;&lt;br /&gt;Pero sirve para entender el chiste de arriba (cortesía de &lt;a href="http://www.xkcd.com/"&gt;xkcd&lt;/a&gt;, como no). Ante ustedes, ¡un sandwitch de salchicha polaca inversa!&lt;br /&gt;&lt;br /&gt;&lt;div class="footnotes" id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; El más famoso turista espacial relacionado con la informática es Mark Shuttleworth, empresario instigador de &lt;b&gt;Ubuntu&lt;/b&gt;.&lt;/div&gt;&lt;br /&gt;&lt;div class="sources"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/aa260976%28VS.60%29.aspx#Mtps_DropDownFilterText"&gt;Notación Húngara&lt;/a&gt;: por Charles Simoyi.&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Polish_notation"&gt;Notación Polaca&lt;/a&gt; (wikipedia inglesa)&lt;/div&gt;&lt;br /&gt;&lt;a class="reltext" onclick="return Mostra('rel')"&gt;Posts relacionados&lt;/a&gt;&lt;br /&gt;&lt;div class="related" id="rel"&gt;&lt;a href="http://civada.blogspot.com/2008/05/csi-xiii-el-lenguaje-de-las-mquinas.html"&gt;El lenguaje de las máquinas&lt;/a&gt;&lt;br /&gt;&lt;a href="http://civada.blogspot.com/2008/11/csi-xiii-lenguajes-y-gramticas-i-ii.html"&gt;Lenguajes y gramáticas&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150691805752037383-7803348957834402106?l=civada.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://civada.blogspot.com/feeds/7803348957834402106/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1150691805752037383&amp;postID=7803348957834402106" title="2 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/7803348957834402106" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/7803348957834402106" /><link rel="alternate" type="text/html" href="http://civada.blogspot.com/2009/10/csi-xviii-los-hungaros-nombran-con.html" title="CSI XVIII: Los húngaros nombran con prefijos" /><author><name>Delirium</name><uri>http://www.blogger.com/profile/08408043740617685786</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150691805752037383.post-5035519500078715982</id><published>2009-08-22T11:12:00.002+02:00</published><updated>2009-08-23T10:27:51.130+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Informática" /><title type="text">CSI XVII: El álgebra de Boole</title><content type="html">&lt;span style="font-size: 95%;"&gt;Demasiado tiempo hacía que no escribía acerca de las &lt;b&gt;Cosas que Sí se dan en Informática&lt;/b&gt;. Pero mi retiro veraniego me ha despertado del letargo y me ha traído, con el viento levantino, los recuerdos de una de las primeras asignaturas que estudié en la carrera y que constituye una base esencial de la propia informática. Me refiero al Diseño Lógico. Mi idea era ir más allá y hablar de lenguajes de descripción de sistemas electrónicos, que tan olvidados e inútiles les resultan a los informáticos que se decantaron por los lenguajes de alto nivel.&lt;br /&gt;&lt;br /&gt;Pero para entender de qué trata éste es necesario disminuir un poco las pretensiones e introducir algo todavía más elemental, que se estudia en el primer curso de la carrera y que, a menos que la especialización te conduzca por áreas de informática industrial o electrónica, se pierde con facilidad. Se trata del &lt;b&gt;Álgebra de Boole&lt;/b&gt;, que hoy, en este capítulo de Cosas que Sí se dan en Informática, presentaremos: tanto en su definición matemática, como en su utilidad electrónica.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="fullpost" style="font-size: 95%;"&gt;El Álgebra de Boole toma su nombre de &lt;a href="http://es.geocities.com/modelo_booleano/BIOGRAFIA.htm"&gt;George Boole&lt;/a&gt;, matemático y filósofo inglés del s. XIX. Sus estudios acerca de la lógica le llevaron a desarrollar un modelo matemático con el fin de analizar el razonamiento humano y de realizar operaciones con sentencias. De su trabajo surgió la estructura matemática que asigna a cada sentencia el valor de VERDADERO (o 1) y FALSO (o 0) y define las operaciones matemáticas que pueden realizarse sobre estos elementos.&lt;br /&gt;&lt;br /&gt;Porque es eso mismo lo que conforma una &lt;i&gt;estructura algebraica&lt;/i&gt;: un conjunto de elementos y un conjunto de operaciones definidas sobre los elementos. El álgebra de Boole tiene forma de &lt;i&gt;anillo&lt;/i&gt;: esto significa que las operaciones definidas satisfacen ciertas propiedades. En la wikipedia pueden continuar con &lt;a href="http://es.wikipedia.org/wiki/Estructura_algebraica"&gt;este tema&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Los elementos del álgebra de Boole son pues dos, que llamaremos &lt;b&gt;0&lt;/b&gt; y &lt;b&gt;1&lt;/b&gt;. Las operaciones básicas que se pueden realizar sobre estos elementos son 3: disyunción (&lt;b&gt;OR&lt;/b&gt;, o suma), conjunción (&lt;b&gt;AND&lt;/b&gt;, o multiplicación) y negación (&lt;b&gt;NOT&lt;/b&gt;, o inversión). Los dos primeros son operadores &lt;i&gt;binarios&lt;/i&gt;, esto es, requieren dos elementos como entrada. La negación se aplica sobre un sólo operando: es &lt;i&gt;unario&lt;/i&gt;, pues. Bien, si hasta ahora ha sido sencillo, lo que viene ahora lo es más.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Las tablas de verdad básicas definen el comportamiento de los operadores para las entradas&lt;/b&gt;. O lo que es lo mismo: su resultado.&lt;br /&gt;&lt;br /&gt;&lt;table border="0" cellpadding="20"&gt;&lt;tr valign="top"&gt;&lt;td&gt;&lt;table style="background: honeydew none repeat scroll 0% 0%; color: black;" border="1" cellpadding="5" cellspacing="0"&gt;&lt;caption&gt;OR&lt;/caption&gt;&lt;tbody&gt;&lt;tr style="background: lightgreen none repeat scroll 0% 0%; color: black;"&gt;&lt;th&gt;A&lt;/th&gt;&lt;th&gt;B&lt;/th&gt;&lt;td style="background: rgb(255, 208, 208) none repeat scroll 0% 0%;"&gt;&lt;b&gt;A OR B&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;center&gt;0&lt;/center&gt;&lt;/td&gt;&lt;td&gt;&lt;center&gt;0&lt;/center&gt;&lt;/td&gt;&lt;td style="background: rgb(255, 240, 240) none repeat scroll 0% 0%;"&gt;&lt;center&gt;0&lt;/center&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;center&gt;0&lt;/center&gt;&lt;/td&gt;&lt;td&gt;&lt;center&gt;1&lt;/center&gt;&lt;/td&gt;&lt;td style="background: rgb(255, 240, 240) none repeat scroll 0% 0%;"&gt;&lt;center&gt;1&lt;/center&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;center&gt;1&lt;/center&gt;&lt;/td&gt;&lt;td&gt;&lt;center&gt;0&lt;/center&gt;&lt;/td&gt;&lt;td style="background: rgb(255, 240, 240) none repeat scroll 0% 0%;"&gt;&lt;center&gt;1&lt;/center&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;center&gt;1&lt;/center&gt;&lt;/td&gt;&lt;td&gt;&lt;center&gt;1&lt;/center&gt;&lt;/td&gt;&lt;td style="background: rgb(255, 240, 240) none repeat scroll 0% 0%;"&gt;&lt;center&gt;1&lt;/center&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;td&gt;&lt;table style="background: honeydew none repeat scroll 0% 0%; color: black;" border="1" cellpadding="5" cellspacing="0"&gt;&lt;caption&gt;AND&lt;/caption&gt;&lt;tbody&gt;&lt;tr style="background: lightgreen none repeat scroll 0% 0%; color: black;"&gt;&lt;th&gt;A&lt;/th&gt;&lt;th&gt;B&lt;/th&gt;&lt;td style="background: rgb(255, 208, 208) none repeat scroll 0% 0%;"&gt;&lt;b&gt;A AND B&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;center&gt;0&lt;/center&gt;&lt;/td&gt;&lt;td&gt;&lt;center&gt;0&lt;/center&gt;&lt;/td&gt;&lt;td style="background: rgb(255, 240, 240) none repeat scroll 0% 0%;"&gt;&lt;center&gt;0&lt;/center&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;center&gt;0&lt;/center&gt;&lt;/td&gt;&lt;td&gt;&lt;center&gt;1&lt;/center&gt;&lt;/td&gt;&lt;td style="background: rgb(255, 240, 240) none repeat scroll 0% 0%;"&gt;&lt;center&gt;0&lt;/center&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;center&gt;1&lt;/center&gt;&lt;/td&gt;&lt;td&gt;&lt;center&gt;0&lt;/center&gt;&lt;/td&gt;&lt;td style="background: rgb(255, 240, 240) none repeat scroll 0% 0%;"&gt;&lt;center&gt;0&lt;/center&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;center&gt;1&lt;/center&gt;&lt;/td&gt;&lt;td&gt;&lt;center&gt;1&lt;/center&gt;&lt;/td&gt;&lt;td style="background: rgb(255, 240, 240) none repeat scroll 0% 0%;"&gt;&lt;center&gt;1&lt;/center&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;td&gt;&lt;table style="background: honeydew none repeat scroll 0% 0%; color: black;" border="1" cellpadding="5" cellspacing="0"&gt;&lt;caption&gt;NOT&lt;/caption&gt;&lt;tbody&gt;&lt;tr style="background: lightgreen none repeat scroll 0% 0%; color: black;"&gt;&lt;th&gt;A&lt;/th&gt;&lt;td style="background: rgb(255, 208, 208) none repeat scroll 0% 0%;"&gt;&lt;b&gt;NOT A&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;center&gt;0&lt;/center&gt;&lt;/td&gt;&lt;td style="background: rgb(255, 240, 240) none repeat scroll 0% 0%;"&gt;&lt;center&gt;1&lt;/center&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;center&gt;1&lt;/center&gt;&lt;/td&gt;&lt;td style="background: rgb(255, 240, 240) none repeat scroll 0% 0%;"&gt;&lt;center&gt;0&lt;/center&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;Explicar una tabla de verdad es casi innecesario: la primera tabla describe la operación OR: &lt;b&gt;0 OR 0&lt;/b&gt; da como resultado &lt;b&gt;0&lt;/b&gt;. En cambio, &lt;b&gt;0 OR 1&lt;/b&gt;, &lt;b&gt;1 OR 0&lt;/b&gt; y &lt;b&gt;1 OR 1&lt;/b&gt; dan como resultado &lt;b&gt;1&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;Aunque no es adecuado, viene bien evaluar una sentencia disyuntiva a un valor de verdad para acabar de entender la correspondencia lógica. La frase &lt;i&gt;Marta tiene un abrigo azul &lt;b&gt;o&lt;/b&gt; tiene una chaqueta colorada&lt;/i&gt; es cierta (verdadera: 1) si alguna de las sentencias que la forman -tiene un abrigo azul, tiene una chaqueta colorada- es verdadera. Para que la conjunción sea cierta (&lt;i&gt;Marta tiene un abrigo azul &lt;b&gt;y&lt;/b&gt; tiene una chaqueta colorada&lt;/i&gt;) es necesario que las dos sentencias individuales -los operandos- sean verdaderos. De este modo se entiende la tabla de verdad de la AND.&lt;br /&gt;&lt;br /&gt;&lt;div style="float:right; margin:0 0 10px 30px;"&gt;&lt;table style="background: honeydew none repeat scroll 0% 0%; color: black;" border="1" cellpadding="5" cellspacing="0"&gt;&lt;caption&gt;XOR&lt;/caption&gt;&lt;tbody&gt;&lt;tr style="background: lightgreen none repeat scroll 0% 0%; color: black;"&gt;&lt;th&gt;A&lt;/th&gt;&lt;th&gt;B&lt;/th&gt;&lt;td style="background: rgb(255, 208, 208) none repeat scroll 0% 0%;"&gt;&lt;b&gt;A XOR B&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;center&gt;0&lt;/center&gt;&lt;/td&gt;&lt;td&gt;&lt;center&gt;0&lt;/center&gt;&lt;/td&gt;&lt;td style="background: rgb(255, 240, 240) none repeat scroll 0% 0%;"&gt;&lt;center&gt;0&lt;/center&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;center&gt;0&lt;/center&gt;&lt;/td&gt;&lt;td&gt;&lt;center&gt;1&lt;/center&gt;&lt;/td&gt;&lt;td style="background: rgb(255, 240, 240) none repeat scroll 0% 0%;"&gt;&lt;center&gt;1&lt;/center&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;center&gt;1&lt;/center&gt;&lt;/td&gt;&lt;td&gt;&lt;center&gt;0&lt;/center&gt;&lt;/td&gt;&lt;td style="background: rgb(255, 240, 240) none repeat scroll 0% 0%;"&gt;&lt;center&gt;1&lt;/center&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;center&gt;1&lt;/center&gt;&lt;/td&gt;&lt;td&gt;&lt;center&gt;1&lt;/center&gt;&lt;/td&gt;&lt;td style="background: rgb(255, 240, 240) none repeat scroll 0% 0%;"&gt;&lt;center&gt;0&lt;/center&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;Mediante sencillas combinaciones de los tres operadores básicos podemos obtener los operadores derivados, que nos sirven para representar otras relaciones lógicas, entre las que se encuentran la &lt;i&gt;o exclusiva&lt;/i&gt;, la &lt;i&gt;implicación&lt;/i&gt; o la &lt;i&gt;equivalencia&lt;/i&gt;. Es posible que a muchos de los lectores les suene esto, ya que las tablas de verdad son las herramientas empleadas en el estudio de la &lt;a href="http://es.wikipedia.org/wiki/L%C3%B3gica_proposicional"&gt;lógica proposicional&lt;/a&gt;, que se cursa típicamente en el instituto. Los operadores derivados más frecuentes tienen sus propios símbolos. En la tabla de al lado se muestra una &lt;i&gt;o exclusiva&lt;/i&gt; o &lt;b&gt;XOR&lt;/b&gt;. La función XOR puede ser construida a partir de operaciones básicas, aunque no de modo sencillo. Sin embargo, resulta muy útil a los informáticos y es ampliamente empleada, como veremos enseguida.&lt;br /&gt;&lt;br /&gt;Las representaciones de estos operandos son muy diversas y los informáticos preferimos la que emplea &lt;a href="http://en.wikipedia.org/wiki/Logic_gate"&gt;puertas lógicas&lt;/a&gt;. Y sin embargo... ¡un momento! ¿qué pintamos los informáticos aquí?. ¿Quién nos ha dado vela en este entierro?.&lt;br /&gt;&lt;br /&gt;Pues en realidad fue Claude Shannon, uno de los grandes, quien nos dio vela. Ya hablamos de Shannon cuando describíamos el &lt;a href="http://civada.blogspot.com/2008/02/csi-x-cuando-la-cosas-ocupan-menos.html"&gt;mínimo de información&lt;/a&gt; necesaria para codificar una cadena de bits. Pero antes de ocuparse de la teoría de la información, Shannon demostró que el álgebra de Boole se podía utilizar en el análisis y la síntesis de la conmutación y de los &lt;b&gt;circuitos digitales&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;Un circuito digital es un circuito electrónico que emplea señales eléctricas que representan (mediante la tensión) dos valores: 0 y 1. El circuito, visto como una &lt;i&gt;caja negra&lt;/i&gt; consta de una serie de entradas y unas salidas. Lo que Shannon demostró es que cualquier salida puede ser producida a partir de las entradas mediante una combinación de operadores booleanos, esto es, mediante un conjunto de puertas lógicas, interconectadas de cierto modo. De este modo podemos ver cualquier transformación de entradas en salidas como la aplicación de cierta función (operación) lógica&lt;a href="#fn1"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;. A esto se le llama circuito, o sistema, &lt;i&gt;combinacional&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div style="float:right; margin:0 0 10px 10px;"&gt;&lt;table border="0" cellpadding="10"&gt;&lt;tr valign="middle"&gt;&lt;td&gt;&lt;table style="background: honeydew none repeat scroll 0% 0%; color: black;" border="1" cellpadding="5" cellspacing="0"&gt;&lt;caption&gt;SUMADOR&lt;/caption&gt;&lt;tbody&gt;&lt;tr style="background: lightgreen none repeat scroll 0% 0%; color: black;"&gt;&lt;th&gt;A&lt;/th&gt;&lt;th&gt;B&lt;/th&gt;&lt;td style="background: rgb(255, 208, 208) none repeat scroll 0% 0%;"&gt;&lt;b&gt;Suma&lt;/b&gt;&lt;/td&gt;&lt;td style="background: rgb(255, 208, 208) none repeat scroll 0% 0%;"&gt;&lt;b&gt;Carry&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;center&gt;0&lt;/center&gt;&lt;/td&gt;&lt;td&gt;&lt;center&gt;0&lt;/center&gt;&lt;/td&gt;&lt;td style="background: rgb(255, 240, 240) none repeat scroll 0% 0%;"&gt;&lt;center&gt;0&lt;/center&gt;&lt;/td&gt;&lt;td style="background: rgb(255, 240, 240) none repeat scroll 0% 0%;"&gt;&lt;center&gt;0&lt;/center&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;center&gt;0&lt;/center&gt;&lt;/td&gt;&lt;td&gt;&lt;center&gt;1&lt;/center&gt;&lt;/td&gt;&lt;td style="background: rgb(255, 240, 240) none repeat scroll 0% 0%;"&gt;&lt;center&gt;1&lt;/center&gt;&lt;/td&gt;&lt;td style="background: rgb(255, 240, 240) none repeat scroll 0% 0%;"&gt;&lt;center&gt;0&lt;/center&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;center&gt;1&lt;/center&gt;&lt;/td&gt;&lt;td&gt;&lt;center&gt;0&lt;/center&gt;&lt;/td&gt;&lt;td style="background: rgb(255, 240, 240) none repeat scroll 0% 0%;"&gt;&lt;center&gt;1&lt;/center&gt;&lt;/td&gt;&lt;td style="background: rgb(255, 240, 240) none repeat scroll 0% 0%;"&gt;&lt;center&gt;0&lt;/center&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;center&gt;1&lt;/center&gt;&lt;/td&gt;&lt;td&gt;&lt;center&gt;1&lt;/center&gt;&lt;/td&gt;&lt;td style="background: rgb(255, 240, 240) none repeat scroll 0% 0%;"&gt;&lt;center&gt;0&lt;/center&gt;&lt;/td&gt;&lt;td style="background: rgb(255, 240, 240) none repeat scroll 0% 0%;"&gt;&lt;center&gt;1&lt;/center&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;td&gt;&lt;a title="Circuito lógico de un sumador sencillo de un bit"&gt;&lt;img src="http://img44.imageshack.us/img44/2050/180pxhalfadder.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;Así, por ejemplo, un circuito básico podría ser el el que suma dos bits. Recordemos que la suma de dos bits era sencilla: 0 + 0 = 0, 0 + 1 = 1, 1 + 0 = 1, 1 + 1 = 0 y me llevo 1 (acarreo). Un sumador simple (&lt;i&gt;half-adder&lt;/i&gt;) de un bit tiene dos entradas y dos salidas (la suma y el acarreo). Lo llamamos simple para diferenciarlo del completo, que añadiría como nueva entrada el acarreo del anterior. De este modo podríamos construir sumadores de cualquier número de bits sin más que encadenar la salida del acarreo de uno a la entrada del otro. Pero nosotros nos quedaremos con el simple, para no complicar el circuito.&lt;br /&gt;&lt;br /&gt;El sumador que vemos emplea una puerta AND (la de abajo de la imagen) y una &lt;b&gt;puerta XOR&lt;/b&gt;, la superior, que ya presentamos anteriormente. Con las tablas de verdad de ambas puertas, es muy sencillo jugar a poner unos y ceros en las entradas y ver cómo los resultados coinciden con los de la suma.&lt;br /&gt;&lt;br /&gt;Puede parecer que un sumador de un bit sólo sirve para jugar, pero de hecho, es la base del cálculo de todas las operaciones que realizan los computadores. Sin embargo es cierto que los ingenieros que construyen circuitos lógicos tienen herramientas para no tener que estar trabajando con miles de puertas lógicas cada vez que pretenden diseñar una nueva unidad aritmética para un computador, por poner ejemplo. Qué pinta tiene alguno de los lenguajes para expresar circuitos lógicos de manera sencilla y potente será explicado en posteriores entregas.&lt;br /&gt;&lt;br /&gt;¡Un saludo y hasta la próxima!&lt;br /&gt;&lt;br /&gt;&lt;div class="footnotes" id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; ¿De qué manera se produce "físicamente" la transformación de dos niveles de tensión a las entradas de una puerta en un nivel de tensión a la salida que corresponda al resultado de la puerta?. Bien eso depende la tecnología empleada y sería necesario entender física de semiconductores para explicarlo. Queda fuera del alcance de este blog.&lt;/div&gt;&lt;br /&gt;&lt;div class="sources"&gt;&lt;a href="http://www.play-hookey.com/digital/xor_function.html"&gt;Infinidad de circuitos digitales&lt;/a&gt; construidos de forma incremental.&lt;br /&gt;&lt;a href="http://es.wikipedia.org/wiki/%C3%81lgebra_de_Boole"&gt;Álgebra de Boole&lt;/a&gt; en la wikipedia en español: se incide en la representación como como conmutación de circuitos.&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/File:Half_Adder.svg"&gt;La imagen del half adder&lt;/a&gt; es de dominio público&lt;/div&gt;&lt;br /&gt;&lt;a class="reltext" onclick="return Mostra('rel')"&gt;Posts relacionados&lt;/a&gt;&lt;br /&gt;&lt;div class="related" id="rel"&gt;&lt;a href="http://civada.blogspot.com/2008/02/csi-x-cuando-la-cosas-ocupan-menos.html"&gt;Compresión de datos&lt;/a&gt;&lt;br /&gt;&lt;a href="http://civada.blogspot.com/2009/02/csi-xiv-los-numeros-de-los-computadores.html"&gt;Los números de los computadores&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150691805752037383-5035519500078715982?l=civada.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://civada.blogspot.com/feeds/5035519500078715982/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1150691805752037383&amp;postID=5035519500078715982" title="2 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/5035519500078715982" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/5035519500078715982" /><link rel="alternate" type="text/html" href="http://civada.blogspot.com/2009/08/csi-xvii-el-algebra-de-boole.html" title="CSI XVII: El álgebra de Boole" /><author><name>Delirium</name><uri>http://www.blogger.com/profile/08408043740617685786</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150691805752037383.post-167447864311799630</id><published>2009-05-24T13:03:00.002+02:00</published><updated>2009-08-13T12:23:38.595+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Informática" /><title type="text">CSI XVI: los números de los computadores (II)</title><content type="html">&lt;span style="font-size: 95%;"&gt;Si recuerdan el ya lejano último post &lt;a href="http://civada.blogspot.com/2009/02/csi-xiv-los-numeros-de-los-computadores.html"&gt;acerca de la informática&lt;/a&gt;, recordarán que había motivos para estar mosqueado. Muy mosqueado, de hecho, porque vimos que los bancos nos podían chulear con facilidad la parte fraccionaria de los ahorros. Pero eso es porque todavía no les he enseñado &lt;b&gt;cómo representar números reales en los computadores&lt;/b&gt;. Y tranquilos, que eso es precisamente lo que voy a comentar hoy.&lt;br /&gt;&lt;br /&gt;Ustedes los humanos emplean un punto (o una coma) o notación científica para representar un número con decimales. Pero la cosa es un poco más compleja si no se pueden valer de esos artificios. Para expresar números reales en un ordenador, la solución más sencilla es convenir que una parte de la ristra de unos y ceros represente la parte entera y el restos de unos y ceros representen la parte decimal. Se dedican &lt;b&gt;n&lt;/b&gt; bits para la parte entera y &lt;b&gt;p&lt;/b&gt; para la fraccionaria. Por supuesto, &lt;b&gt;n&lt;/b&gt; y &lt;b&gt;p&lt;/b&gt; son fijos para un computador, para no hacerse un lío. Por eso este sistema se denomina de &lt;b&gt;coma fija&lt;/b&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="fullpost" style="font-size: 95%;"&gt;&lt;a href="http://es.wikipedia.org/wiki/Coma_fija"&gt;La coma fija&lt;/a&gt; mola, porque no tenemos que aprender nada nuevo (aparte de lo que aprendieron en el anterior post). Con 8 bits podemos dedicar 5 a la parte entera y otros 3 a la parte decimal, por ejemplo. De manera que si usamos &lt;i&gt;Complemento a 2&lt;/i&gt; para representar la primera (para la decimal no empleamos ninguna codificación especial) entonces podemos representar un rango  de números que va desde -16.0 hasta +15.875. La precisión la marca la cantidad de bits en la parte fraccionaria, claro, que en este caso es de 0.125 (1/(2^3)).&lt;br /&gt;&lt;br /&gt;La coma fija no mola, porque operaciones entre números dentro del rango de representación exceden con facilidad el propio rango. Un ejemplo decimal: 0.345 * 0,001 = 0.000345. Si gastamos 3 dígitos para la parte entera y tres para la parte decimal, es evidente que el resultado de la multiplicación con este sistema sería 0. Y nos volvemos a quedar sin céntimos en los bancos.&lt;br /&gt;&lt;br /&gt;Para hacer esto más flexible se inventó &lt;b&gt;la coma flotante&lt;/b&gt;. La coma flotante es un lío, pero que es muy útil. Un número real se representa como:&lt;br /&gt;&lt;br /&gt;&lt;div class="code" style="font-size:110%;"&gt;R = M * B&lt;sup&gt;E&lt;/sup&gt; donde:&lt;br /&gt;M es número fraccionario, donde se utiliza un bit para representar el signo (como en &lt;b&gt;Signo y magnitud&lt;/b&gt;).&lt;br /&gt;B es la base. 2, en casi todos los casos.&lt;br /&gt;E es el exponente, que se representa en &lt;b&gt;exceso Z&lt;/b&gt; (esto no lo he explicado).&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Si lo pensamos un poco, esto no es más que una aproximación a la notación científica. Por ejemplo, -0.000456 = -456 * 10&lt;sup&gt;-6&lt;/sup&gt;, donde el signo es negativo, la mantisa 456, la base 10 y el exponente -6. La complejidad de la coma flotante es ajustar cada campo a un número limitado de bits. Y para eso vamos a aprovechar hasta el máximo.&lt;br /&gt;&lt;br /&gt;El formato IEEE754 de simple precisión (el más conocido de representación de reales) emplea un total de 32 bits: 1 para el sigo, 8 para el exponente y 24 para la mantisa. &lt;br /&gt;&lt;br /&gt;¿Cómo?. ¿Que no le salen las cuentas?. Claro, amigo, lo que usted no sabe es que los ingenieros aprovechamos todo el espacio que podemos. Y le ganamos un bit a la mantisa de forma sencilla. Porque, si usted quiere utilizar el formato IEEE754 es porque tiene algo que representar, aunque sea muy pequeño. Un ejemplo:&lt;br /&gt;&lt;br /&gt;0,0000101 (binario). ¿Por qué tengo que almacenar en la mantisa los cuatro ceros? Al fin y al cabo, 0,0000101 = 1,01 * 2&lt;sup&gt;-5&lt;/sup&gt;. Sólo tengo que ajustar el exponente (restándole 5). Lo bueno es que esto lo puedo hacer para todos los números, de forma que, sea cual sea el número a representar, el primer bit de la mantisa será 1. Y como el primer bit de la mantisa es siempre 1, me puedo ahorrar el representarlo (¡siempre que luego me acuerde de él a la hora de interpretar el número!). De este modo tenemos 24 bits para representar la mantisa, aunque sólo empleemos 23.&lt;br /&gt;&lt;br /&gt;A la operación de dejar un único bit significativo (1) a la izquierda de la coma se le llama &lt;i&gt;normalizar la mantisa&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Hemos dicho que tras normalizar la mantisa conviene ajustar el exponente. Pero no hemos hablado de cómo se representa este mismo, ni qué significa &lt;i&gt;exceso Z&lt;/i&gt;. Es una cosa tan tonta que da risa. En exceso Z se escoge cualquier número (Z) para representar el cero. Cualquier número entero A se expresa como el natural A+Z. Por ejemplo, en exceso 127, el -7 se expresa como 120 (-7 + 127). El 3 se expresa como 130 (3 + 127).&lt;br /&gt;&lt;br /&gt;Precisamente 127 es el Z escogido para representar el exponente en el formato IEEE754. Por tanto, ya disponemos de todos los elementos para ponernos a calcular números reales. Buenos, nos falta dar el orden de los campos: Signo - Exponente - Mantisa. Ya está.&lt;br /&gt;&lt;br /&gt;&lt;div class="code" style="font-size:110%;"&gt;Representar -209.5625 en coma flotante IEEE754 (simple precisión)&lt;br /&gt;&lt;b&gt;S&lt;/b&gt; = 1 (signo negativo)&lt;br /&gt;Parte entera: 209 = 11010001&lt;br /&gt;Parte fraccionaria: .5625 = 0.1001 (2&lt;sup&gt;-1&lt;/sup&gt; + 2&lt;sup&gt;-4&lt;/sup&gt;)&lt;br /&gt;&lt;b&gt;Mantisa&lt;/b&gt;: (parte entera.parte fraccionaria) 11010001.1001 = 1.10100011001 * 2&lt;sup&gt;+7&lt;/sup&gt;&lt;br /&gt;&lt;b&gt;Exponente&lt;/b&gt; Z = 127 + 7 = 134, que en binario es 10000110&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;S E&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;M&lt;br /&gt;De lo cual: -209.5625 = 1 10000110 10100011001000000000000&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Y ya hemos aprendido a representar números reales. Por supuesto, al ser un rango de representación finito, con este formato también tenemos cierto límite en la precisión (determinado por los 24 bits de mantisa). Para los más avezados dejo su cálculo. &lt;br /&gt;&lt;br /&gt;Yo quiero incidir en otra cosa, que no sé si habrán notado. A pesar de que hemos detallado la representación de números en distintos formatos, al final, en su computador, todos los formatos no son sino ristras de unos y ceros, de modo que la misma longaniza puede ser un número entero negativo, real, o positivo. O no ser un número. Por eso a la hora de escribir un programa es fundamental dar a conocer al computador cómo debe interpretar un valor. Esto se consigue con los &lt;b&gt;tipos de datos&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;Cuando queremos gastar un valor, empleamos variables para almacenarlas. Y en gran parte de lenguajes es necesario declarar el tipo de dato de una variable antes de gastarla, para que el computador sepa cómo debe operar con ella.&lt;br /&gt;&lt;br /&gt;En C, el lenguaje más extendido, si declaramos una variable como &lt;b&gt;int&lt;/b&gt; (entero) lo más posible es que le digamos al computador que esa variable debe representarse en Complemento a 2&lt;a href="#fn1"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;. Si declaramos un &lt;b&gt;float&lt;/b&gt; es muy posible que para representar esa variable se gasten 32 bits (simple precisión) en IEEE754. Y si declaramos un &lt;b&gt;unsigned char&lt;/b&gt;, entonces estamos gastando 8 bits en una representación binaria sin signo (positivo).&lt;br /&gt;&lt;br /&gt;Y ahora el chiste:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Si los androides algún día sueñan con ovejas eléctricas no olvides declarar el contador de ovejas como long int.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://imgs.xkcd.com/comics/cant_sleep.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 540px; height: 178px;" src="http://imgs.xkcd.com/comics/cant_sleep.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;¿Que ha pasado?. Que el contador de ovejas estaba declarado como int (16 bits). Y el rango de representación es (Ca2) -32768 (1000000 00000000) - 32767 (01111111 1111111). Al sumar uno a 32767 el número de ovejas se convierte en negativo. De haber declarado el contador como long int, posiblemente habría tenido 32 bits para representar la cuenta. Eso significa que un androide insomne habría contado hasta 2147483647 (2&lt;sup&gt;31&lt;/sup&gt;-1) antes de que sucediera lo mismo. Y si declarara la variable como &lt;b&gt;unsigned long&lt;/b&gt; (sin signo), podría contar hasta 4294967295. La siguiente cuenta sería 0, ya que el computador jamás interpretaría este número como negativo.&lt;br /&gt;&lt;br /&gt;Ojalá me disculpen. Tan sólo quería compartir humor friqui con ustedes.&lt;br /&gt;&lt;br /&gt;&lt;div class="footnotes" id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; El número de bits con los que se representa y el formato de representación dependen de la arquitectura del procesador. Por eso es un error asumir que un int tiene siempre, por ejemplo, 32 bits.&lt;/div&gt;&lt;br /&gt;&lt;div class="sources"&gt;Apuntes clase. Pero en la wikipedia &lt;a href="http://es.wikipedia.org/wiki/Coma_flotante"&gt;también viene bien explicado&lt;/a&gt;&lt;br /&gt;Pinar me pasó el link a la tira: &lt;a href="http://xkcd.com"&gt;más humor&lt;/a&gt; en su web.&lt;/div&gt;&lt;br /&gt;&lt;a class="reltext" onclick="return Mostra('rel')"&gt;Posts relacionados&lt;/a&gt;&lt;br /&gt;&lt;div class="related" id="rel"&gt;&lt;a href="http://civada.blogspot.com/2009/02/csi-xiv-los-numeros-de-los-computadores.html"&gt;Representación de números (I)&lt;/a&gt;&lt;br /&gt;&lt;a href="http://civada.blogspot.com/2008/01/csi-ix-codificacin-de-datos.html"&gt;Codificación de datos (I)&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150691805752037383-167447864311799630?l=civada.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://civada.blogspot.com/feeds/167447864311799630/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1150691805752037383&amp;postID=167447864311799630" title="2 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/167447864311799630" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/167447864311799630" /><link rel="alternate" type="text/html" href="http://civada.blogspot.com/2009/05/csi-xv-los-numeros-de-los-computadores.html" title="CSI XVI: los números de los computadores (II)" /><author><name>Delirium</name><uri>http://www.blogger.com/profile/08408043740617685786</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150691805752037383.post-7068625775030047442</id><published>2009-02-10T22:32:00.003+01:00</published><updated>2009-08-13T12:09:41.188+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Informática" /><title type="text">CSI XV: Los números de los computadores</title><content type="html">&lt;span style="font-size: 95%;"&gt;Con la crisis, amigos míos, todos echamos números. &lt;a href="http://www.computing.es/noticias/200902090051/El-Defensor-del-Pueblo-salta-a-Vista-con-Business-Integration.aspx"&gt;Los hay que no&lt;/a&gt;, pero es lo que tiene vivir con dinero de los demás: atrofia el ingenio para buscarse alternativas, libres y gratuitas. Echar números es sólo necesario si vas algo apurado, como el 90% de población española.&lt;br /&gt;&lt;br /&gt;Para echar números se inventaron las calculadoras, hace ya muchos años. Y de de la evolución las calculadoras nació el microprocesador, hace ya 38 años. Tiene huevos, por otro lado, que como respuesta a la crisis la vicepresidenta diga que nos vamos &lt;a href="http://www.elpais.com/articulo/espana/Espero/Consejo/imponga/anos/suspension/juez/Tirado/elpepiesp/20081005elpepinac_2/Tes"&gt;a montar en el chip&lt;/a&gt; para abandonar el crecimiento basado en el ladrillo. Porque para eso han tenido tiempo, y de sobra, dos administraciones socialistas, otras dos peperas, unas tres y media socialistas de nuevo y un trozo de la de la UCD. A buenas horas, (vice)presidenta.&lt;br /&gt;&lt;br /&gt;Retomemos que me enciendo. Lo que les voy a contar hoy en &lt;b&gt;C&lt;/b&gt;osas que &lt;b&gt;S&lt;/b&gt;í se dan en &lt;b&gt;I&lt;/b&gt;nformática es cómo cuentan los computadores. O, dicho de otro modo, &lt;b&gt;cómo representan los números los ordenadores&lt;/b&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="fullpost" style="font-size: 95%;"&gt;A estas horas es &lt;i&gt;vox populi&lt;/i&gt; (excepto quizá para nuestros representantes públicos) que los computadores utilizan ceros y unos para representar la información. Antiguamente eran campos magnéticos en núcleos de ferrita, hoy pueden ser en forma de surcos en discos ópticos y mañana quizá sea en cuantos de energía en átomos. Dejando la &lt;a href="http://en.wikipedia.org/wiki/Fuzzy_logic"&gt;lógica difusa&lt;/a&gt; al margen la cosa sigue teniendo la misma base: haber o no haber. 1 o 0. Y ahora veamos qué es eso del binario.&lt;br /&gt;&lt;br /&gt;Utilizar dos caracteres para representar números tiene la misma dificultad que emplear 10. Que es lo que hacemos los humanos continuamente. El llamado sistema decimal no es más que un sistema &lt;i&gt;posicional&lt;/i&gt; de representación con diez símbolos (0, 1, 2, 3, ..., 9). Es posicional porque la posición importa en el valor de un símbolo, como sabrán todos aquellos que han sido llamados "ceros a la izquierda". Así, el número 459 significa, exactamente:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: 110%;"&gt;&lt;b&gt;4&lt;/b&gt;*10&lt;sup&gt;2&lt;/sup&gt; + &lt;b&gt;5&lt;/b&gt;*10&lt;sup&gt;1&lt;/sup&gt; + &lt;b&gt;9&lt;/b&gt;(*10&lt;sup&gt;0&lt;/sup&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;El carácter más significativo -el 4- lo colocamos más a la izquierda y se multiplica por la base -10- elevado a su posición -la tercera-. Análogamente para el resto.&lt;br /&gt;&lt;br /&gt;Con el binario, la representación es idéntica. Sólo tenemos que tomar la base 2.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: 110%;"&gt;&lt;b&gt;1&lt;/b&gt;*2&lt;sup&gt;8&lt;/sup&gt; + &lt;b&gt;1&lt;/b&gt;*2&lt;sup&gt;7&lt;/sup&gt; + &lt;b&gt;1&lt;/b&gt;*2&lt;sup&gt;6&lt;/sup&gt; + &lt;b&gt;0&lt;/b&gt;*2&lt;sup&gt;5&lt;/sup&gt; + &lt;b&gt;0&lt;/b&gt;*2&lt;sup&gt;4&lt;/sup&gt; + &lt;b&gt;1&lt;/b&gt;*2&lt;sup&gt;3&lt;/sup&gt; + &lt;b&gt;0&lt;/b&gt;*2&lt;sup&gt;2&lt;/sup&gt; + &lt;b&gt;1&lt;/b&gt;*2&lt;sup&gt;1&lt;/sup&gt; + &lt;b&gt;1&lt;/b&gt;*2&lt;sup&gt;0&lt;/sup&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Nos da exactamente 459, si le apetece hacer la suma. O nos da exactamente &lt;b&gt;111001011&lt;/b&gt;. Utilizar un sistema decimal en lugar de cualquier otro es completamente arbitrario o fortuito. De hecho, no está del todo claro por qué gastamos un sistema decimal, aunque muy posiblemente sea por tener diez dedos. Desde luego, es un argumento de peso.&lt;br /&gt;&lt;br /&gt;Como escribir 111001011 es un rollo, incluso para una cantidad pequeña como 459, los informáticos nos apañamos para representar grandes números empleando otras bases más cómodas, como la octal o hexadecimal. En la primera empleamos los símbolos 0, 1, 2, 3, 4, 5, 6 y 7. En la segunda, todos los anteriores y además 8, 9, A, B, C, D, E y F. Es inmediato pasar de binario a ocal y hexadecimal (y a la inversa). Tan sólo tenemos que agrupar los símbolos binarios de 3 en tres y representar el correspondiente caracter octal, o de cuatro en cuatro y sustituir por el correspondiente símbolo hexadecimal:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: 110%;"&gt;111 001 011 = 713 (7*8&lt;sup&gt;2&lt;/sup&gt; + 1*8&lt;sup&gt;1&lt;/sup&gt; + 3*8&lt;sup&gt;0&lt;/sup&gt;)&lt;br /&gt;1 1100 1011 = 1CB (1*16&lt;sup&gt;2&lt;/sup&gt; + 12*16&lt;sup&gt;1&lt;/sup&gt; + 11*16&lt;sup&gt;0&lt;/sup&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;¡Maravilloso!. Ya tenemos hasta cuatro maneras de representar lo mismo. Cualquier número que se nos ocurra puede ser representado de cualquiera de ellas, &lt;i&gt;aunque no dentro de un computador&lt;/i&gt;. porque la aritmética de un computador es &lt;i&gt;finita&lt;/i&gt;, lo que no es sino un modo de decir que tiene límites: números mayores de cierto rango (o menores) no nos cabrán. Pero no nos preocuparemos por ellos todavía.&lt;br /&gt;&lt;br /&gt;¿Y nos sirve de algo lo visto en tiempos de crisis?. Pues no, porque aún no podemos representar la realidad, mucho más dramática que lo visto hasta ahora. La cruda realidad cuenta con &lt;span style="color:red;"&gt;números rojos&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Los números rojos son negativos y usted lo tiene muy fácil para representarlos porque hace trampa: pone un &lt;b&gt;-&lt;/b&gt; delante de ellos y ya. ¡Es hacer trampa porque añade un símbolo que no estaba en el conjunto inicial de diez!. &lt;em&gt;¿Cómo se las apañaría para representar números negativos sin ningún símbolo añadido?&lt;/em&gt;. A esa pregunta respondieron los informáticos hace mucho tiempo.&lt;br /&gt;&lt;br /&gt;La solución fácil: reservamos una posición, la más significativa, para indicar si un número es positivo o negativo. El resto del número nos da su magnitud. A ésta forma de representación se le llama &lt;b&gt;signo y magnitud&lt;/b&gt;, por razones que explicaré otro día. Si el primer símbolo es un cero, el número es positivo. Si es un 1, negativo.&lt;br /&gt;&lt;br /&gt;&lt;div class="code" style="overflow:hidden;"&gt;0 000 -&gt; +0&amp;nbsp;&amp;nbsp;&amp;nbsp;|&amp;nbsp;&amp;nbsp;&amp;nbsp;1 000 -&gt; -0&lt;br /&gt;0 001 -&gt; +1&amp;nbsp;&amp;nbsp;&amp;nbsp;|&amp;nbsp;&amp;nbsp;&amp;nbsp;1 001 -&gt; -1&lt;br /&gt;0 010 -&gt; +2&amp;nbsp;&amp;nbsp;&amp;nbsp;|&amp;nbsp;&amp;nbsp;&amp;nbsp;1 010 -&gt; -2&lt;br /&gt;...&lt;/div&gt;&lt;br /&gt;Ésta forma de representación, además de contar con la curiosidad de disponer de dos ceros, es un peñazo, porque requiere analizar el signo antes de ponerse a operar con los números y hacer sumas y restas y aritmética en general. Hay métodos más cómodos.&lt;br /&gt;&lt;br /&gt;La forma que efectivamente se gasta un montón es el llamado &lt;b&gt;Complemento a 2&lt;/b&gt;. El Ca2 representa los números positivos como los naturales que vimos al principio. Los negativos, en cambio, los representa &lt;i&gt;invirtiendo todos lo bits y sumando uno al resultado&lt;/i&gt; (lo que se llama hacer el complemento a dos&lt;a href="#fn1"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;). Sumar, por cierto, es tan fácil como en base decimal: cero mas cero es cero; cero mas uno, uno; y uno más uno, cero y me llevo uno. &lt;br /&gt;Veamos un ejemplo de representación en Ca2:&lt;br /&gt;&lt;br /&gt;&lt;div class="code" style="overflow:hidden;"&gt;0000 -&gt; +0&amp;nbsp;&amp;nbsp;&amp;nbsp;|&amp;nbsp;&amp;nbsp;&amp;nbsp;1111 -&gt; -1 ( invertimos1(0001) = 1110 + 1 = 1111 )&lt;br /&gt;0001 -&gt; +1&amp;nbsp;&amp;nbsp;&amp;nbsp;|&amp;nbsp;&amp;nbsp;&amp;nbsp;1110 -&gt; -2 ( invertimos2(0010) = 1101 + 1 = 1110 )&lt;br /&gt;0010 -&gt; +2&amp;nbsp;&amp;nbsp;&amp;nbsp;|&amp;nbsp;&amp;nbsp;&amp;nbsp;1101 -&gt; -3 ( invertimos3(0011) = 1100 + 1 = 1101 )&lt;/div&gt;&lt;br /&gt;¿Por qué es tan interesante esto que a primera vista parece un lío?. Bueno, podemos ver a la primera si un número es positivo o negativo. Y ya no tenemos dos ceros. Y sobretodo nos permite sumar a la primera cantidades negativas y positivas. Un ejemplo:&lt;br /&gt;&lt;br /&gt;&lt;div class="code" style="overflow:hidden;"&gt;-20 + 10 = -10&lt;br /&gt;&lt;br /&gt;-20 -&gt; invertimos20(010100) = 101011 + 1 = 101100&lt;br /&gt;+10 -&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;001010&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;110110 -&gt; Ca2(110110) = 001001 + 1 =&gt; 001010 = 8 + 2 = 10&lt;/div&gt;&lt;br /&gt;La suma nos ha dado -10 directamente, sin tener que hacer ajustes posteriores. Y no los habrá que hacer, a menos que que el resultado no sea representable (no nos quepa) en la longitud de bits máxima que tenemos. Así que nosotros nos quedaremos con éste formato para representar los enteros.&lt;br /&gt;&lt;br /&gt;De todos modos, este formato tampoco representa la realidad. Porque si usted va al banco, transfiere unos 120 euros y le cobran un 4% de comisión (5 euros) se quedará de piedra. Primero: porque hay que ser &lt;i&gt;joputas&lt;/i&gt; para cobrar un 4% de comisión por una mierda de operación bancaria que se realiza a través de Internet. Y segundo, porque el 4% de 120 no son 5 euros, sino 4.80. ¿Quién se ha quedado sus 20 céntimos en tiempos de crisis?&lt;br /&gt;&lt;br /&gt;El banco, evidentemente. Porque sus ordenadores no pueden representar cantidades decimales, no al menos hasta que yo les explique cómo. Y redondean (que no truncan) para fastidiarle a usted. Pero les contaré cómo representar cantidades fraccionales sin hacer de nuevo trampa e introducir más símbolos como el '&lt;b&gt;.&lt;/b&gt;'.&lt;br /&gt;&lt;br /&gt;¡Eso será más adelante, en &lt;b&gt;Cosas que Sí de dan en Informática&lt;/b&gt;!&lt;br /&gt;&lt;br /&gt;&lt;div class="footnotes" id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; ver la referencia para una explicación más convincente.&lt;/div&gt;&lt;br /&gt;&lt;div class="sources"&gt;Apuntes de clase. ¡Esto se estudia en primero!&lt;br /&gt;&lt;a href="http://es.wikipedia.org/wiki/Sistema_binario"&gt;Sistema binario&lt;/a&gt;. Wikipedia.&lt;br /&gt;&lt;a href="http://es.wikipedia.org/wiki/Complemento_a_dos"&gt;Complemento a dos&lt;/a&gt;. Wikipedia.&lt;/div&gt;&lt;br /&gt;&lt;a class="reltext" onclick="return Mostra('rel')"&gt;Posts relacionados&lt;/a&gt;&lt;br /&gt;&lt;div class="related" id="rel"&gt;&lt;a href="post"&gt;Nombre&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150691805752037383-7068625775030047442?l=civada.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://civada.blogspot.com/feeds/7068625775030047442/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1150691805752037383&amp;postID=7068625775030047442" title="2 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/7068625775030047442" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/7068625775030047442" /><link rel="alternate" type="text/html" href="http://civada.blogspot.com/2009/02/csi-xiv-los-numeros-de-los-computadores.html" title="CSI XV: Los números de los computadores" /><author><name>Delirium</name><uri>http://www.blogger.com/profile/08408043740617685786</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150691805752037383.post-5662469781924519953</id><published>2009-01-10T19:59:00.000+01:00</published><updated>2009-01-10T20:00:09.310+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Informática" /><title type="text">Cómo escribir código inmantenible</title><content type="html">&lt;span style="font-size: 95%;"&gt;Últimamente algo ando espeso, lo siento. Tengo la cabeza tan llena de cosas del trabajo que no me da tiempo a escribir nada bueno para el blog, ni a pensar en nuevos temas ni nada. Disculpen si esto baja un poco el ritmo de actualización. Y de originalidad.&lt;br /&gt;&lt;br /&gt;Como saben ustedes (y si no lo saben se lo cuento), yo soy programador. Programador de C, para ser más exacto. Ahórrense las condolencias: me gusta mi trabajo. Programo sistemas empotrados, que es como ordenadores, pero más pequeños y desnudos. Todo una delicia, si no atendemos al componente sexual del asunto.&lt;br /&gt;&lt;br /&gt;La cuestión es que hace unos meses encontré este vetusto texto de Internet: &lt;a href="http://freeworld.thc.org/root/phun/unmaintain.html"&gt;How to write unmanteinable code&lt;/a&gt;, y me pegué una &lt;i&gt;jartá&lt;/i&gt; a reír. Comento, para quien no lo sepa, que el código con el que funcionan los programas difícilmente es escrito por una sola persona y, en cualquier caso, es muy fácil que otra tenga que leerlo y entenderlo para actualizarlo, añadir funcionalidades y quitar otras. A eso se le llama &lt;i&gt;mantener una aplicación&lt;/i&gt;. El problema que tenemos es que, por lo general, cada uno tiene un estilo a la hora de programar y entender un programa que ha escrito otro puede ser tremendamente complicado.  &lt;br /&gt;&lt;br /&gt;Para conseguir código mantenible existen centenares de guías. Y normas. Pero sólo existe una para escribir código inmantenible. Les traduzco algunas de las recomendaciones más graciosas que he encontrado en ella&lt;a href="#fn1"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;[Advertencia]: si usted no es informático, el concepto que tenemos usted y yo de &lt;i&gt;lo que es gracioso&lt;/i&gt; y lo que no lo es puede variar mucho.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="fullpost" style="font-size: 95%;"&gt;&lt;b&gt;Nombrado de variables&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Si llamas a tus variables a, b, c, entonces será imposible encontrarlas usando un buscador común. Además, nadie tendrá ni idea de para qué sirven. Anima a los lectores de tu programa a encontrar cada ocurrencia leyendo todas la lineas de todos los ficheros: así entenderán mejor el programa.&lt;br /&gt;&lt;br /&gt;A.C.R.O.N.Y.M.S.: utiliza acrónimos para mantener el código carente de emoción. Los hombres de verdad jamás explican los acrónimos: los entienden por genética.&lt;br /&gt;&lt;br /&gt;Reusa nombres: nunca está de más ser ecológicos. Siempre que el lenguaje lo permita, llama a funciones, variables y parámetros con los mismo nombres. El objetivo es obligar al mantenedor a que conozca perfectamente las reglas de ámbito del lenguaje.&lt;br /&gt;&lt;br /&gt;Elige nombres con connotaciones emocionales irrelevantes y opera con ellos, p.ej.&lt;br /&gt;&lt;div class="code" style="overflow:auto;"&gt;marypoppins = (superman + starship) / god;&lt;/div&gt;&lt;br /&gt;Esto confundirá al lector, que suele asociar nombres de variable de algún modo con el valor que contiene.&lt;br /&gt;&lt;br /&gt;Asegúrate de que cada función realiza un poco más (o menos) de lo que su nombre indica. Como simple ejemplo, un método llamado isValid(x) puede tener como efecto colateral convertir x a binario y almacenarlo en una base de datos.&lt;br /&gt;&lt;br /&gt;Emplea referencias ocultas a películas. Usa nombres constantes como &lt;i&gt;LancelotsFavouriteColour&lt;/i&gt; en vez de azul y asígnalo al valor hexadecimal de 0x0204FB. El color es idéntico al azul de la pantalla y el programador mantenedor tendrá que buscar alguna herramienta gráfica para asaber qué color es. Sólo alguien muy familiar con los Monty Python (y los caballeros de la mesa cuadrada) sabrá que el color favorito de Lancelot era el azul. Si el programador mantenedor no puede citar de memoria las películas enteras de los Monty Python, entonces no tiene futuro como programador.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Camuflaje&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Incluye secciones de código que están comentadas pero que a primera vista no lo estén. Por ejemplo:&lt;br /&gt;&lt;div class="code" style="height:120px;"&gt;for(j=0; j &amp;lt; array_len; j+  =8)&lt;br /&gt;            {&lt;br /&gt;            &amp;nbsp;&amp;nbsp;total += array[j+0 ];&lt;br /&gt;            &amp;nbsp;&amp;nbsp;total += array[j+1 ];&lt;br /&gt;            &amp;nbsp;&amp;nbsp;total += array[j+2 ]; /* Main body of&lt;br /&gt;            &amp;nbsp;&amp;nbsp;total += array[j+3]; * loop is unrolled&lt;br /&gt;            &amp;nbsp;&amp;nbsp;total += array[j+4]; * for greater speed.&lt;br /&gt;            &amp;nbsp;&amp;nbsp;total += array[j+5]; */&lt;br /&gt;            &amp;nbsp;&amp;nbsp;total += array[j+6 ];&lt;br /&gt;            &amp;nbsp;&amp;nbsp;total += array[j+7 ];&lt;br /&gt;            }&lt;/div&gt;&lt;br /&gt;Recuerda al mantenedor las reglas de asociación añadiendo instrucciones que resultan ser comentarios.&lt;br /&gt;&lt;div class="code" style="overflow:auto;"&gt;Importantvalue = a/*p  /* divide by the value pointed */;&lt;/div&gt;&lt;br /&gt;Si tienes suerte y el compilador permite comentarios anidados, puedes reservar muchas sorpresas hasta que se descubra que no existe división alguna.&lt;br /&gt;&lt;br /&gt;Esconde las definiciones de las macros, entre comentarios inútiles. Así el programador se aburrirá y no llegará a descubrirla. Asegúrate de que la macro reemplaza una asignación perfectamente normal por cualquier operación rara, por ejemplo:&lt;br /&gt;&lt;div class="code" style="overflow:auto;"&gt;#define a=b a=0-b&lt;/div&gt;&lt;br /&gt;Aunque ya tengas una variable llamada xy_z, no hay ninguna razón para que no puedas emplear también otras con nombres similares, como xy_Z, xy__z, _xy_z, _xyz, XY_Z, xY_z, and Xy_z. Sé creativo: variables que se distinguen tan sólo por las mayúsculas y barras bajas tienen la ventaja de confundir a quienes recuerdan los nombres por cómo suenan, en vez de por su representación exacta.&lt;br /&gt;&lt;br /&gt;Elige el mejor operador de sobrecarga: En C++, sobrecarga los operadores +,-,*,/ para hacer cosas totalmente diferentes de suma, resta... Después de todo, si Stroustroup puede usar el operador de desplazamiento para entrada/salida, ¿por qué no ser igual de creativo?. Si sobrecargas +, asegúrate de que i = i + 5 tiene un significado completamente distinto a  i += 5.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Documentación&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Miente en los comentarios. Es muy sencillo: no actualices los comentarios al actualizar el código.&lt;br /&gt;&lt;br /&gt;Documenta cómo y no el porqué. Documenta sólo los detalles de lo que el programa hace (incluyendo los autoincrementos), no lo que pretende conseguir. Así, si hay algún error, el que lo tenga que arreglar no tendrá pistas para sabe qué es lo que el código debería estar haciendo.&lt;br /&gt;&lt;br /&gt;Nunca documentes errores en el código. Si sospechas que hay un bug, mantenlo en secreto. Si crees que el código puede ser mejorado o reorganizado, por el amor de Dios, no lo digas. Recuerda las palabras en la película Bambi: &lt;i&gt;Si no puede decir nada bonito, mejor no digas nada&lt;/i&gt;. Qué sucederá si el que lo escribió ve tu comentario?. ¿Y un cliente?. ¡Podrías estar despedido!. En cambio, un comentario del tipo: /* This needs to be fixed! */ puede hacer maravillas, sobretodo si no se sabe a qué se refiere. De este modo nadie podrá ser criticado.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Diseño&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Gasta &lt;i&gt;arrays&lt;/i&gt; de tres dimensiones: montones de ellos. Mueve datos entre ellos de originales maneras, llenando las columnas de uno con las filas de otro. Si el desplazamiento es de uno, sin razón aparente, bien hecho. Hace que el mantenedor se ponga nervioso.&lt;br /&gt;&lt;br /&gt;Utiliza todas la variables globales que puedas. Si Dios no hubiera querido que usáramos variables globales, no las habría inventado. Cada función debe usar y dar valor a un par de variables globales al menos, incluso aunque no exista ninguna buena razón para ello. Al fin y al cabo, el mantenedor se figurará que es una especie de detective y estará contento de cumplir una tarea que separa a los verdaderos programadores de los aficionadillos.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Testing&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Que tu proyecto sólo funcione en modo debug. Si tienes distintas configuraciones de proyecto, asegúrate de que tan sólo funciona con una de ellas. Es muy sencillo de realizar con directivas de preproceso: &lt;i&gt;#define TESTING&lt;/i&gt; te da la oportunidad de tener dos secciones del código independientes. Dentro de #ifdef TESTING asigna los valores necesarios para que funcione el programa. Si alguien elimina el define, o mejor aún, no compila con la directiva adecuada, el programa no funcionará.&lt;br /&gt;&lt;br /&gt;Testear es de cobardes. Un programador valiente se saltará este paso. Demasiados programadores temen perder su empleo y tienen miedo del jefe y del cliente. Este miedo les paraliza y reduce su productividad. Estudios han demostrado que eliminando las fases de test se puede adelantar las fechas de entrega, algo positivo para el proceso. Sin el miedo, las innovación y experimentación pueden florecer. El trabajo del programador es producir código, y mantenerlo es tarea de otros.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;(...)&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;En fin, la lista tiene años y tiene multitud de ideas gloriosas para escribir código inmantenible. Si tiene tiempo y es usted programador de Java, C o C++ échele un vistazo. Si quiere escribir bien, en cambio, lo tiene más complicado.&lt;br /&gt;&lt;br /&gt;&lt;div class="footnotes" id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; La traducción es muy libre, aviso. Yo he escogido ejemplos que se aplican a C porque es el lenguaje con el que trabajo. Y se pueden hacer muchas muchas guarradas en C...&lt;/div&gt;&lt;br /&gt;&lt;div class="sources"&gt;&lt;a href="http://freeworld.thc.org/root/phun/unmaintain.html"&gt;How to write unmmaintainable code&lt;/a&gt;&lt;br /&gt;&lt;b&gt;C traps and Pitfalls&lt;/b&gt;, de Andrew Koenig pone el ejemplo del puntero-comentario.&lt;/div&gt;&lt;br /&gt;&lt;a class="reltext" onclick="return Mostra('rel')"&gt;Posts relacionados&lt;/a&gt;&lt;br /&gt;&lt;div class="related" id="rel"&gt;&lt;a href="http://civada.blogspot.com/2007/06/el-trabajo-de-aitor-menta-i.html"&gt;El trabajo de Aitor Menta&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150691805752037383-5662469781924519953?l=civada.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://civada.blogspot.com/feeds/5662469781924519953/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1150691805752037383&amp;postID=5662469781924519953" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/5662469781924519953" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/5662469781924519953" /><link rel="alternate" type="text/html" href="http://civada.blogspot.com/2009/01/cmo-escribir-cdigo-inmantenible.html" title="Cómo escribir código inmantenible" /><author><name>Delirium</name><uri>http://www.blogger.com/profile/08408043740617685786</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150691805752037383.post-4278482554798642949</id><published>2008-11-22T09:40:00.003+01:00</published><updated>2009-08-12T12:54:23.772+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Informática" /><title type="text">CSI XIV: Lenguajes y gramáticas (i II)</title><content type="html">&lt;span style="font-size: 95%;"&gt;Es obligatorio leer &lt;a href="http://civada.blogspot.com/2008/11/csi-xiii-lenguajes-y-gramticas-i.html"&gt;el post anterior&lt;/a&gt;...&lt;br /&gt;&lt;br /&gt;Nos habíamos quedado en una pregunta: ¿Cómo se relaciona las gramáticas formales con los lenguajes de programación de alto nivel? Pues verán, los lenguajes de programación están especificados mediante una gramática que determina la secuencia de palabras aceptable en un programa. Y nosotros, los humanos, hacemos algo parecido cuando queremos entendernos. Si yo les digo "rosa un pasea perro tranquilamente" no estoy hablando español, por más que las palabras que gaste existan en la lengua española. Existe una gramática que debo cumplir.&lt;br /&gt;&lt;br /&gt;Es importante notar una diferencia respecto al ejemplo anterior de las &lt;i&gt;aes&lt;/i&gt; y las &lt;i&gt;bes&lt;/i&gt;. Lo que antes eran letras que conformaban el alfabeto ahora se corresponden con palabras que integran el vocabulario. Las reglas de la gramática castellana se aplican a las palabras, las cuales reciben &lt;i&gt;categorías gramaticales&lt;/i&gt;, como sustantivo, adjetivo, verbo, etc. En informática en vez de palabras hablamos de &lt;i&gt;tokens&lt;/i&gt;. Tokens típicos son &lt;i&gt;identificador&lt;/i&gt;, &lt;i&gt;declaración&lt;/i&gt;, &lt;i&gt;expresión&lt;/i&gt;...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="fullpost" style="font-size: 95%;"&gt;Vamos a crear una sencilla gramática, que será una burda imitación de nuestro lenguaje. Los símbolos no terminales serán: ORACIÓN, SUJETO, PREDICADO, DETERMINANTE, SUSTANTIVO, VERBO, ADJETIVO y ADVERBIO. Los no terminales serán el conjunto {&lt;i&gt;un, el, este, aquel, perro, gato, pastel, azul, pequeño, pasea, camina, garbosamente, rápidamente&lt;/i&gt;}.&lt;br /&gt;&lt;br /&gt;En primer lugar estableceremos la relación entre los terminales y las categorías gramaticales representadas por símbolos no terminales. En nuestro caso esto es evidente y la representación se entenderá fácilmente:&lt;br /&gt;&lt;div style="border: thin solid; font-family: courier new; font-size:120%; text-align: left; background-color: white; padding: 4px; color: black; margin-top:10px;"&gt;DETERMINANTE = {"un", "el", "este"}&lt;br /&gt;SUSTANTIVO = {"perro", "gato", "pastel"}&lt;br /&gt;VERBO = {"pasea", "camina"}&lt;br /&gt;ADJETIVO = {"azul", "pequeño"}&lt;br /&gt;ADVERBIO = {"garbosamente", "rápidamente"}&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Si la secuencia de letras corresponde a una palabra con un no-terminal asociado viene determinado por el &lt;b&gt;análisis léxico&lt;/b&gt;. &lt;i&gt;Garvosamente&lt;/i&gt; no es un adverbio, por mucho que lo parezca: es una burrada. Decimos entonces que se trata de un error léxico.&lt;br /&gt;&lt;br /&gt;Nuestra gramática relaciona los símbolos no terminales y tiene esta pinta, que seguro les sonará del cole:&lt;br /&gt;&lt;div style="border: thin solid; font-family: courier new; font-size:120%; text-align: left; background-color: white; padding: 4px; color: black; margin-top:10px;"&gt;ORACIÓN := SUJETO PREDICADO&lt;br /&gt;SUJETO := DETERMINANTE SUSTANTIVO | DETERMINANTE SUSTANTIVO ADJETIVO&lt;br /&gt;PREDICADO := VERBO | VERBO ADVERBIO&lt;/div&gt;&lt;a href="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Tomando el no-terminal ORACIÓN como símbolo inicial, ya pueden dedicarse a averiguar si los siguientes secuencias de palabras caen dentro de nuestro pequeño lenguaje. Por ejemplo, son parte de nuestro lenguaje: &lt;i&gt;este perro azul camina rápidamente&lt;/i&gt;, &lt;i&gt;un gato pasea&lt;/i&gt; o &lt;i&gt;Este pastel azul camina garbosamente&lt;/i&gt;. En el último caso la oración no tiene ningún sentido, pero es sintácticamente impecable. El último paso para dotar de sentido una oración en un lenguaje es realizar un &lt;b&gt;análisis semántico&lt;/b&gt;. En las lenguas naturales éste depende del contexto y es posible que en cierto ámbito pudiera tener sentido que un pastel caminara y, además, lo hiciera con cierto estilo.&lt;br /&gt;&lt;br /&gt;Nuestra especificación de un lenguaje deja mucho que desear, por supuesto y sólo recuerda vagamente a los idiomas que hablamos. Los lenguajes que usamos los humanos son lenguajes naturales y la mayoría de las gramáticas que emplean son &lt;i&gt;ambiguas&lt;/i&gt;, esto es, para una secuencia de entrada admiten distintas interpretaciones. Los lenguajes informáticos tratan de eliminar toda posible ambigüedad mediante reglas expresas en el tratamiento de la entrada, reglas de precedencia... sin embargo hay ocasiones en los que el comportamiento del &lt;b&gt;compilador&lt;/b&gt;, que es quien debe leerse el programa y determinar su validez, se deja sin determinar.&lt;br /&gt;&lt;br /&gt;Y en este punto ha aparecido un concepto nuevo: el &lt;b&gt;compilador&lt;/b&gt;. El compilador es un programa que, tomando un conjunto de archivos con un lenguaje que podemos entender, genera un archivo ejecutable: una imagen en memoria que se puede ejecutar. Un programa, vamos. Y para entender lo que pone en el fichero, el compilador tiene que realizar las mismas acciones que acabamos de describir.&lt;br /&gt;&lt;br /&gt;Es decir, que el compilador primero lee letra a letra el archivo y crea una secuencia de &lt;i&gt;tokens&lt;/i&gt;. En nuestra analogía, si el compilador tomara como entrada una frase como Un pastel pasea azul, la salida del análisis léxico sería la secuencia: DETERMINANTE SUSTANTIVO VERBO ADJETIVO. El compilador a veces duda: si lee una p tras un espacio no sabe si corresponde a un SUSTANTIVO (&lt;i&gt;pastel&lt;/i&gt;, &lt;i&gt;perro&lt;/i&gt;) a un VERBO (&lt;i&gt;pasea&lt;/i&gt;) o a un ADJETIVO (&lt;i&gt;pequeño&lt;/i&gt;). Y a veces el programador piensa que el compilador va a entender una cosa y entiende otra. (Estoy en condiciones de poner ejemplos a petición de los informáticos).&lt;br /&gt;&lt;br /&gt;Con la secuencia de tokens formada, el compilador toma el símbolo inicial de la gramática y juega a validar esa secuencia con las reglas de la misma (&lt;b&gt;análisis sintáctico&lt;/b&gt;). De este modo decide si un programa es &lt;i&gt;correcto&lt;/i&gt;. Que un programa sea sintácticamente correcto no significa que funcione como el programador espera, del mismo modo que nuestro ejemplo del pastel paseante funcionaba sintácticamente sin tener sentido. A veces las frases sin sentido nos hacen gracia, pero un programa sin sentido no hace ni puta gracia.&lt;br /&gt;&lt;br /&gt;En serio.&lt;br /&gt;&lt;br /&gt;Precisamente leí hace poco que el primer compilador fue desarrollado por una mujer, &lt;a href="http://en.wikipedia.org/wiki/Grace_Hopper"&gt;Grace Hopper&lt;/a&gt;, una de las pioneras de la informática. Programó los computadores más importantes de la época (años 50 y 60) y partici´po en el desarrollo de los lenguajes COBOL y FORTRAN, dos de los lenguajes con más arraigo entre los matemáticos y físicos y que son tan buenos que hoy en día, más de 40 años después, se siguen empleando&lt;br /&gt;&lt;br /&gt;En resumen, quizá hayan visto ustedes el código de algún programa y les haya parecido complicadísimo (sin contar que hay gente que escribe código fatal). Desengáñense. Ese lenguaje hay un conjunto relativamente reducido de &lt;i&gt;tokens&lt;/i&gt; y su gramática es tremendamente más sencilla y restrictiva que todo aquello que les enseñaron en el cole, con sus excepciones y dialectismos.&lt;br /&gt;&lt;br /&gt;¡Los programadores estamos, definitivamente, sobrevalorados!&lt;br /&gt;&lt;br /&gt;&lt;div class="footnotes" id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; Los informáticos me podrán decir que esta gramática no se ajusta a la forma normal de Chomsky y mogollón de cosas más. Es cierto que no he querido complicar demasiado la explicación: no pretendo que nadie apruebe una asignatura de teoría de autómatas o lenguajes formales gracias mis posts. Como dije, pretendo tan sólo mostrar que Informática es algo más que páginas web y bases de datos.&lt;/div&gt;&lt;br /&gt;&lt;div class="sources"&gt;Apuntes de clase.&lt;br /&gt;En la wikipedia podemos ver &lt;a href="http://es.wikipedia.org/wiki/Imagen:CompilationScheme-Spanish.png"&gt;un diagrama sencillo&lt;/a&gt; de cómo actúa un compilador.&lt;/div&gt;&lt;br /&gt;&lt;a class="reltext" onclick="return Mostra('rel')"&gt;Posts relacionados&lt;/a&gt;&lt;br /&gt;&lt;div class="related" id="rel"&gt;&lt;a href="http://civada.blogspot.com/2008/05/csi-xiii-el-lenguaje-de-las-mquinas.html"&gt;El lenguaje de las máquinas&lt;/a&gt;&lt;br /&gt;&lt;a href="http://civada.blogspot.com/2008/11/csi-xiii-lenguajes-y-gramticas-i.html"&gt;Lenguajes y gramáticas (I)&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150691805752037383-4278482554798642949?l=civada.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://civada.blogspot.com/feeds/4278482554798642949/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1150691805752037383&amp;postID=4278482554798642949" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/4278482554798642949" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/4278482554798642949" /><link rel="alternate" type="text/html" href="http://civada.blogspot.com/2008/11/csi-xiii-lenguajes-y-gramticas-i-ii.html" title="CSI XIV: Lenguajes y gramáticas (i II)" /><author><name>Delirium</name><uri>http://www.blogger.com/profile/08408043740617685786</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150691805752037383.post-2211703378091029262</id><published>2008-11-22T09:38:00.002+01:00</published><updated>2009-08-12T12:55:14.541+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Informática" /><title type="text">CSI XIV: Lenguajes y gramáticas (I)</title><content type="html">&lt;span style="font-size: 95%;"&gt;Éste post pretende ser, no exactamente una continuación, sino un complemento a &lt;a href="http://civada.blogspot.com/2008/05/csi-xiii-el-lenguaje-de-las-mquinas.html"&gt;éste post acerca del lenguaje de las máquinas&lt;/a&gt;. Recordando un poco de qué iba, vimos cómo en principio las instrucciones recibidas por máquinas y computadores eran de tipo mecánico. Con el tiempo se pudo almacenar estas instrucciones en forma de memorias magnéticas donde series de niveles de tensión determinaban el comportamiento de los componentes del procesador.&lt;br /&gt;&lt;br /&gt;Se desarrollaron luego distintos niveles de abstracción sobre el lenguaje en el que se expresaban estas instrucciones (programas). El &lt;b&gt;lenguaje ensamblador&lt;/b&gt; consistía en una serie secuencial de códigos que representaban directamente las instrucciones que podía ejecutar un procesador. Era completamente dependiente del mismo. Sin embargo, por encima del ensamblador surgieron lenguajes con un nivel mayor de abstracción, independientes de la máquina en el lenguaje que emplean. Se les llama &lt;i&gt;lenguajes de alto nivel&lt;/i&gt;. Los lenguajes más empleados hoy en día son de este tipo, aunque hay muchas diferencias entre ellos.&lt;br /&gt;&lt;br /&gt;En el post de hoy generalizaremos la representación de un lenguaje de alto nivel y veremos en qué medida sus conceptos son tomados de la lingüística y se basan en la teoría de grupos.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="fullpost" style="font-size: 95%;"&gt;Empezaremos desde abajo: llamamos &lt;b&gt;alfabeto&lt;/b&gt; a un conjunto finito de símbolos (que llamaremos letras). Una &lt;b&gt;palabra&lt;/b&gt; es una secuencia de finita de letras de un alfabeto. Hasta ahí todo normal, ¿no?. Venga un ejemplo: &lt;b&gt;&amp;Delta;&lt;/b&gt; es un alfabeto compuesto por las letras &lt;i&gt;a&lt;/i&gt; y &lt;i&gt;b&lt;/i&gt;. No nos liemos con más. Algunas palabras posibles sobre ese alfabeto son &lt;i&gt;aaaab&lt;/i&gt; o &lt;i&gt;baaba&lt;/i&gt;. Al conjunto de todas las palabras que se pueden formar con este alfabeto se le denomina el &lt;b&gt;lenguaje universal&lt;/b&gt; sobre el alfabeto &lt;b&gt;&amp;Delta;&lt;/b&gt;, &lt;i&gt;siempre que incluyamos en el mismo la palabra vacía &amp;lambda; (lambda)&lt;/i&gt;. La palabra vacía tiene longitud 0.&lt;br /&gt;&lt;br /&gt;Dado que el lenguaje es un conjunto, se pueden realizar operaciones sobre el mismo y, dependiendo de las propiedades que cumpla, le daremos un nombre u otro. Eso se lo dejaremos a los matemáticos.&lt;br /&gt;&lt;br /&gt;Los lenguajes universales, pese a ser fascinantes por sus propiedades (digo yo) de poco nos sirven en la práctica. Volviendo a un plano más cercano a la vida real, los seres humanos no sólo empleamos un conjunto finito de palabras, sino que además empleamos un orden determinado entre ellas. A este orden se le denomina &lt;b&gt;sintaxis&lt;/b&gt;. Y la &lt;b&gt;gramática&lt;/b&gt; determina las reglas en las que se deben combinar las palabras.&lt;br /&gt;&lt;br /&gt;En informática (y matemáticas) una gramática tiene una definición formal: consta de un conjunto de &lt;i&gt;terminales&lt;/i&gt;, un conjunto de &lt;i&gt;no-terminales&lt;/i&gt; (o símbolos auxiliares), un símbolo no-terminal inicial y un conjunto de las reglas de producción. Las reglas de producción determinan la generación de las palabras del lenguaje. Con un ejemplo esto queda clarísimo.&lt;br /&gt;&lt;br /&gt;Nuestro alfabeto &lt;b&gt;&amp;Delta; = {a,b,&amp;lambda}&lt;/b&gt; podría ser el conjunto de terminales. &lt;b&gt;S&lt;/b&gt; será el símbolo no terminal inicial y &lt;b&gt;A&lt;/b&gt; es el otro no terminal. Las reglas de producción podrían ser estas (enseguida las explico):&lt;br /&gt;&lt;div style="border: thin solid; font-family: courier new; font-size:120%; text-align: left; background-color: white; padding: 4px; color: black; margin-top:10px;"&gt;S := bS | aA | &amp;lambda;&lt;br /&gt;A := aS | bA&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="border: thin solid; font-family: courier new; font-size:120%; text-align: left; background-color: white; padding: 4px; color: black; margin-top:10px;"&gt;Posibles derivaciones:&lt;br /&gt;S -&gt; bS -&gt; b&amp;lambda;: b forma parte del lenguaje.&lt;br /&gt;S -&gt; bS -&gt; baA -&gt; babA -&gt; babaS -&gt; baba&amp;lambda; : baba forma parte del lenguaje.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;a title="Producción en una gramática que genera el lenguaje de las 'a's par" &gt;&lt;img style="float:right; margin:0 0 10px 10px;" src="http://img361.imageshack.us/img361/6206/alfabetoaeshj1.png" border="0" alt="" /&gt;&lt;/a&gt;Ésta gramática genera el lenguaje de las palabras con un número par de &lt;i&gt;aes&lt;/i&gt;. ¿No me creen?. Pues vean. El juego consiste en, empezando en el símbolo inicial, quedarse sin no-terminales. Cuando queden sólo terminales se termina y obtenemos una palabra. El símbolo inicial es &lt;b&gt;S&lt;/b&gt; y decimos que &lt;b&gt;S&lt;/b&gt; &lt;i&gt;deriva directamente&lt;/i&gt; &lt;i&gt;bS&lt;/i&gt; ó &lt;i&gt;aA&lt;/i&gt; ó la palabra vacía (| significa 'o'). Podemos escoger cualquiera de las tres derivaciones. Si escogemos la palabra vacía ya hemos acabado, porque nos hemos quedado sin no-terminales: la palabra vacía tiene 0 &lt;i&gt;aes&lt;/i&gt; y forma parte del alfabeto. Si escogemos &lt;i&gt;bS&lt;/i&gt; tenemos que quitar la &lt;b&gt;S&lt;/b&gt;, y derivamos de nuevo. Posibles secuencias de derivaciones a partir de ésta podría ser las que hemos visto en el ejemplo de arriba o la que se ve en la figura. (en la figura he empleado &lt;i&gt;sigma&lt;/i&gt; para referirme al alfabeto, lo cual suele ser una convención).&lt;br /&gt;&lt;br /&gt;¿Por qué no prueban a jugar siguiendo las reglas? Verán que todas las palabras tienen 0 o un número par de &lt;i&gt;aes&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Y ahora es el momento de cambiar de post, porque si no, esto queda muy largo. &lt;a href="http://civada.blogspot.com/2008/11/csi-xiii-lenguajes-y-gramticas-i-ii.html"&gt;Vayamos al siguiente&lt;/a&gt; para ver qué tiene esto que ver con los lenguajes de programación...&lt;br /&gt;&lt;br /&gt;&lt;div class="footnotes" id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; Esta entrada no se ve bien con IE6, en parte porque yo no he escrito bien HTML (que Firefox se traga), en parte porque Internet Explorer no muestra casi nada bien. Pero bueno, no me enseñaron HTML en la carrera, me enseñaron cosas como ésta que les he contado. Por eso esta sección se llama &lt;b&gt;C&lt;/b&gt;osas que &lt;b&gt;S&lt;/b&gt;i se dan en &lt;b&gt;I&lt;/b&gt;nformática,&lt;/div&gt;&lt;br /&gt;&lt;div class="sources"&gt;Apuntes de clase. Anda que no hace tiempo que estudié esto...&lt;/div&gt;&lt;br /&gt;&lt;a class="reltext" onclick="return Mostra('rel')"&gt;Posts relacionados&lt;/a&gt;&lt;br /&gt;&lt;div class="related" id="rel"&gt;&lt;a href="http://civada.blogspot.com/2008/05/csi-xiii-el-lenguaje-de-las-mquinas.html"&gt;El lenguaje de las máquinas&lt;/a&gt;&lt;br /&gt;&lt;a href="http://civada.blogspot.com/2008/11/csi-xiii-lenguajes-y-gramticas-i-ii.html"&gt;Lenguajes y gramáticas (II)&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150691805752037383-2211703378091029262?l=civada.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://civada.blogspot.com/feeds/2211703378091029262/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1150691805752037383&amp;postID=2211703378091029262" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/2211703378091029262" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/2211703378091029262" /><link rel="alternate" type="text/html" href="http://civada.blogspot.com/2008/11/csi-xiii-lenguajes-y-gramticas-i.html" title="CSI XIV: Lenguajes y gramáticas (I)" /><author><name>Delirium</name><uri>http://www.blogger.com/profile/08408043740617685786</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150691805752037383.post-6377168551576619783</id><published>2008-09-09T18:34:00.008+02:00</published><updated>2008-12-14T11:12:02.646+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Informática" /><title type="text">Crear subetiquetas en Blogger</title><content type="html">&lt;span style="font-size:95%;"&gt;Que Blogger no es especialmente flexible a la hora de personalizar el blog es bien conocido. Lo sabrá cualquiera que haya intentado juguetear un poco con el &lt;i&gt;template&lt;/i&gt;. Wordpress ofrece muchas más características, además de plugins de terceros que se pueden integrar fácilmente (supongo) para personalizar el blog. Yo ya me he peleado unas cuantas veces con mi plantilla cuando he querido hacer algunas cosas un poco especiales: ensanchar el blog, introducir el &lt;i&gt;Seguir leyendo&lt;/i&gt;, definir entradillas personalizadas, y más recientemente pasar del tamaño fijo y ajustar la anchura del blog al tamaño de la pantalla.&lt;br /&gt;&lt;br /&gt;Una cosa que siempre he deseado hacer era utilizar subetiquetas. Es decir: refinar un conjunto de posts (los de la etiqueta &lt;b&gt;Cerveza&lt;/b&gt; en este caso) con otras etiquetas. Esto es bastante útil para clasificar los post en la barra lateral, al menos en un blog como el mío. Los gestores de blogs no entienden de subetiquetas y todas las etiquetas tienen la misma jerarquía. Así que el tema consiste en conseguir que en la barra lateral aparezcan, alineadas en forma de árbol, las etiquetas y subetiquetas que yo desee. Encontré &lt;a href="http://betabloggerfordummies.blogspot.com/2008/03/how-to-classify-blogger-labels.html"&gt;un método muy cómodo&lt;/a&gt; y personalizable, pero que incluía bastante Javascript (además de tener otros inconvenientes). Yo lo quería sin librerías de funciones ni muchas imágenes ni nada de eso. Finalmente se me ocurrieron dos soluciones de aficionado (que funcionan).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="fullpost" style="font-size:95%;"&gt;&lt;b&gt;La solución con falsas etiquetas&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;El problema con Blogger es que no soporta las consultas del tipo: &lt;i&gt;muéstrame todos los posts con la etiqueta 'Cerveza' AND 'Historia'&lt;/i&gt;. No le da la gana&lt;a href="#fn1"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;. Porque Wordpress sí que lo hace y para muestra, &lt;a href="http://curiosoperoinutil.com/category/ciencia/fisica/"&gt;http://curiosoperoinutil.com/category/ciencia/fisica/&lt;/a&gt;. Podéis ver que el blog Curioso pero Inútil tiene en la barra, bajo la categoría &lt;b&gt;Ciencia&lt;/b&gt; muchas subetiquetas, como por ejemplo &lt;b&gt;Física&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;Por otro lado Blogger sí que soporta la búsqueda de cadenas de texto. Así que mi primera solución fue de pillo: emplearía falsas etiquetas con palabras clave, ocultas en cada post que quisiera clasificar bajo la etiqueta de 'Cerveza'. Por ejemplo, &lt;span style="text-decoration:underline;"&gt;en cada post que fuera de Historia de la Cerveza gastaría la palabra oculta &lt;b&gt;cervhistoria&lt;/b&gt;&lt;/span&gt;. Para ocultarla, basta cambiar la propiedad de estilo &lt;i&gt;display&lt;/i&gt;. &lt;br /&gt;&lt;br /&gt;Es decir, escribo, al final de cada post de &lt;b&gt;Cerveza&lt;/b&gt; con la 'subetiqueta' &lt;b&gt;Historia&lt;/b&gt; &amp;lt;span style="display:none;&amp;gt;cervhistoria&amp;lt;/span&amp;gt;.&lt;br /&gt;&lt;br /&gt;Una vez hecho esto podemos consultar todos los posts con la palabra &lt;i&gt;cervhistoria&lt;/i&gt; con la consulta &lt;b&gt;http://civada.blogspot.com/search?q=cervhistoria&lt;/b&gt;&lt;a href="#fn1"&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Y ahora sólo tengo que editar el template del blog para cambiar la barra lateral. A los elementos especiales del blog que están en la barra lateral se les llama &lt;i&gt;widgets&lt;/i&gt;. Hay un &lt;a href="http://help.blogger.com/bin/answer.py?answer=47270#labels"&gt;widget específico para las etiquetas&lt;/a&gt;. En él se recorren todos los nombres de etiquetas de tu blog que Blogger almacena (alfabéticamente) y se muestran como una lista html. Sólo tenemos que 'buscar' la etiqueta deseada (&lt;b&gt;Cerveza&lt;/b&gt;) y entonces iniciar una sublista html. En ella añadiremos los enlaces a las búsquedas de palabras ocultas. &lt;span style="color:red"&gt;(el añadido está en rojo)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Buscamos el widget en el &lt;i&gt;template&lt;/i&gt; y hacemos esto (alguien que haya hecho algo de informática lo entenderá enseguida):&lt;br /&gt;&lt;div class="code" style="height: 200px;"&gt;&amp;lt;b:widget id='Label1' locked='false' title='Etiquetas' type='Label'&gt;&lt;br /&gt;&amp;lt;b:includable id='main'&gt;&lt;br /&gt;&amp;lt;b:if cond='data:title'&gt;&lt;br /&gt;&amp;lt;H2&gt;&amp;lt;data:title/&gt;&amp;lt;/H2&gt; &amp;lt;!-- Esto es la palabra 'Etiquetas'  --&gt;&lt;br /&gt;&amp;lt;/b:if&gt;&lt;br /&gt;&amp;lt;DIV class='widget-content'&gt;&lt;br /&gt;&amp;nbsp;&amp;lt;UL&gt; &amp;lt;!-- Aquí empieza la lista principal  --&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;b:loop values='data:labels' var='label'&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;LI&gt;             &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;b:if cond='data:blog.url == data:label.url'&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;SPAN expr:dir='data:blog.languageDirection'&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;data:label.name/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/SPAN&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/b:if&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;b:else/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;A expr:dir='data:blog.languageDirection' expr:href='data:label.url'&gt;&amp;lt;data:label.name/&gt;&amp;lt;/A&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/b:if&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;SPAN dir='ltr'&gt;(&amp;lt;data:label.count/&gt;)&amp;lt;/SPAN&gt; &amp;lt;!-- Número de posts con la etiqueta  --&gt;&lt;br /&gt;&lt;span style="color:red;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;b:if cond='data:label.name == "Cerveza"'&gt; &amp;lt;!-- Aquí empieza lo bueno --&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;UL style='margin-top:5px;'&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;LI&gt;&amp;lt;A href='http://nombredelblog.blogspot.com/search?q=cervhistoria'&gt;Historia&amp;lt;/A&gt;&amp;lt;/LI&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;LI&gt;&amp;lt;A href='http://nombredelblog.blogspot.com/search?q=cervestilos'&gt;Estilos&amp;lt;/A&gt;&amp;lt;/LI&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/UL&gt; &amp;lt;!-- Fin de la sublista --&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/b:if&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/LI&gt; &amp;lt;!-- Fin de la entrada de Cerveza --&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/b:loop&gt; &amp;lt;!-- Fin del bucle --&gt;&lt;br /&gt;&amp;nbsp;&amp;lt;/UL&gt; &amp;lt;!-- Fin de la lista de entradas --&gt;&lt;br /&gt;&amp;lt;b:include name='quickedit'/&gt;&lt;br /&gt;&amp;lt;/DIV&gt;&lt;br /&gt;&amp;lt;/b:includable&gt;&lt;br /&gt;&amp;lt;/b:widget&gt; &amp;lt;!-- Sanseacabó el widget --&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Y funciona. Veamos las &lt;b&gt;ventajas de este método&lt;/b&gt;.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Es relativamente sencillo.&lt;/li&gt;&lt;li&gt;No hay que trastear mucho el template. Aunque por cada nueva 'subetiqueta' virtual tendremos que añadir una linea nueva, claro.&lt;/li&gt;&lt;li&gt;Es una idea cojonuda&lt;/li&gt;&lt;/ul&gt;Pero veamos las &lt;b&gt;desventajas&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;No son etiquetas de verdad. Nadie se podrá suscribir a los posts de Historia de la Cerveza. Lástima por los historiadores maltasianos. Tampoco tenemos cuenta de posts subetiquetados. Lástima por los amantes de las estadísticas&lt;/li&gt;&lt;li&gt;'Etiquetar' muchos posts antiguos con las nuevas palabras ocultas es un rollo.&lt;/li&gt;&lt;li&gt;El día que a Blogger le de por añadir esta característica tendremos que etiquetar de nuevo y desmontar la paraeta.&lt;/li&gt;&lt;/ul&gt;Así que mirando el template di con una solución más bestia y menos elegante, pero con etiquetas de verdad.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;La solución a lo bruto&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Es muy sencilla: consiste en NO añadir a la lista principal las subetiquetas Y AÑADIRLAS expresamente bajo la etiqueta principal. Para eso gastaremos dos millones de expresiones condicionales. ¿Por qué?. Porque, que yo sepa, Blogger no entiende expresiones condicionales compuestas. Supongamos que tenemos tres subcategorías bajo &lt;b&gt;Cerveza&lt;/b&gt; que son &lt;i&gt;Historia&lt;/i&gt;, &lt;i&gt;Estilos&lt;/i&gt; y &lt;i&gt;Ronda&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;La cosa es (atentos, amantes del pseudo-código)&lt;br /&gt;&lt;div class="code" style="height: 150px;"&gt;PARA todas_las_etiquetas HACER&lt;br /&gt;SI nombre_de_etiqueta NO_ES &lt;i&gt;Historia&lt;/i&gt; NI &lt;i&gt;Estilos&lt;/i&gt; NI &lt;i&gt;Ronda&lt;/i&gt; ENTONCES&lt;br /&gt;&amp;nbsp;(abrimos lista)&lt;br /&gt;&amp;nbsp;...Código del widget...&lt;br /&gt;&amp;nbsp;SI nombre_de_etiqueta ES &lt;i&gt;Cerveza&lt;/i&gt; ENTONCES&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;PARA todas_las_etiquetas HACER&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(empezamos sublista)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;SI nombre_de_etiqueta ES &lt;i&gt;Historia&lt;/i&gt; O &lt;i&gt;Estilos&lt;/i&gt; O &lt;i&gt;Ronda&lt;/i&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Añadimos enlace a la etiqueta como el resto.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(cerramos sublista)&lt;br /&gt;&amp;nbsp;(cerramos lista)&lt;br /&gt;&amp;nbsp;PUES_YASTA&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;El único problema es que en Blogger (&lt;b&gt;QUE YO SEPA&lt;/b&gt;) &lt;a href="http://help.blogger.com/bin/answer.py?answer=46995&amp;topic=12488"&gt;no se puede poner ni NI ni O&lt;/a&gt;. Lo cual es triste para la programación. Porque hay que añadir un mogollón de código. Algo así:&lt;br /&gt;&lt;div class="code" style="height: 200px;"&gt;&amp;lt;div class='widget-content'&gt;&lt;br /&gt;&amp;lt;ul&gt; &amp;lt;!-- Inicio de la lista --&gt;&lt;br /&gt;&amp;lt;b:loop values='data:labels' var='label'&gt;&lt;br /&gt;&lt;span style="color:red"&gt;&amp;nbsp;&amp;lt;b:if cond='data:label.name != &amp;quot;Estilos&amp;quot; '&gt;&lt;br /&gt;&amp;nbsp;&amp;lt;b:if cond='data:label.name != &amp;quot;Historia&amp;quot; '&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;lt;li&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;b:if cond='data:blog.url == data:label.url'&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;span expr:dir='data:blog.languageDirection'&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;data:label.name/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;b:else/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;a expr:dir='data:blog.languageDirection' expr:href='data:label.url'&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;data:label.name/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/a&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/b:if&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;span dir='ltr'&gt;(&amp;lt;data:label.count/&gt;)&amp;lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;lt;/li&gt;&lt;span style="color:red"&gt;&lt;br /&gt;&amp;nbsp;&amp;lt;/b:if&gt;&amp;lt;/b:if&gt; &amp;lt;!-- Tantos cierres como subetiquetas que no han de estar --&gt;&lt;br /&gt;&amp;nbsp;&amp;lt;b:if cond='data:label.name == &amp;quot;Cerveza&amp;quot;'&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;ul style='margin-top:5px;'&gt; &amp;lt;!-- Inicio la sublista --&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;b:loop values='data:labels' var='label'&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;b:if cond='data:label.name == &amp;quot;Estilos&amp;quot; '&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;li&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;b:if cond='data:blog.url == data:label.url'&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;span expr:dir='data:blog.languageDirection'&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;data:label.name/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;b:else/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;a expr:dir='data:blog.languageDirection' expr:href='data:label.url'&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;data:label.name/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/a&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/b:if&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;span dir='ltr'&gt;(&amp;lt;data:label.count/&gt;)&amp;lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/li&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;b:else/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;b:if cond='data:label.name == &amp;quot;Historia&amp;quot; '&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;li&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;b:if cond='data:blog.url == data:label.url'&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;span expr:dir='data:blog.languageDirection'&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;data:label.name/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;b:else/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;a expr:dir='data:blog.languageDirection' expr:href='data:label.url'&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;data:label.name/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/a&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/b:if&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;span dir='ltr'&gt;(&amp;lt;data:label.count/&gt;)&amp;lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/li&gt;       &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/b:if&gt;&amp;lt;/b:if&gt; &amp;lt;!-- Tantos cierres como subetiquetas --&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/b:loop&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/ul&gt; &amp;lt;!-- Fin de la sublista --&gt;&lt;br /&gt;&amp;nbsp;&amp;lt;/b:if&gt; &amp;lt;!-- Si era cerveza --&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;lt;/b:loop&gt;&lt;br /&gt;&amp;lt;/ul&gt; &amp;lt;!-- Fin de la lista --&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Y no queda nada elegante, pero funciona, y funciona bien, como pueden ver en la barra de al lado. Pasemos pues a la enumeración de pros y contras (esta vez en orden inverso).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Contras de esta solución&lt;/b&gt;:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Es un peñazo para el &lt;i&gt;template&lt;/i&gt;, sobretodo si un desea emplear muchas subetiquetas. Hay que tocar mucho código.&lt;/li&gt;&lt;li&gt;Algún día Blogger le dará soporte directamente y todo esto se irá al garete&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;Ventajas&lt;/b&gt;:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Es muy fácil añadir las subetiquetas a los posts ya creados.&lt;/li&gt;&lt;li&gt;Tenemos etiquetas de verdad, a las que uno se puede suscribir. Los maltasianos estarán contentos. Y los amantes de las estadísticas.&lt;/li&gt;&lt;/ul&gt;Hay que hacer notar que, aunque pongamos mogollón de código condicional en el template, éste no se transmite y por tanto no hace que la página 'pese' más. Sí que puteamos un poco a los servidores de blogger, que son los que procesan el template junto con los datos del blog y crean el código html que es efectivamente transferido (el tiempo de proceso del servidor suele ser nimio en comparación con el de transmisión). Pero que se jodan. Haber dado soporte directamente, leñe.&lt;br /&gt;&lt;br /&gt;Y ya está. ¿A que mola?. Yo no lo había visto en ningún blog de Blogger. Sólo hace falta que lo diga para que me salgan 15 ejemplos. Si alguien conoce una manera mejor de hacer lo mismo, que me lo diga, por favor.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Actualización&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blogalacarte.blogspot.com/"&gt;Rô&lt;/a&gt; ha realizado en su blog una explicación detallada del segundo método. La pueden consultar aquí: &lt;a href="http://blogalacarte.blogspot.com/2008/09/modificando-o-widget-de-categorias.html"&gt;Parte I&lt;/a&gt;, &lt;a href="http://blogalacarte.blogspot.com/2008/09/modificando-o-widget-de-categorias_16.html"&gt;Parte II&lt;/a&gt; y &lt;a href="http://blogalacarte.blogspot.com/2008/09/modificando-o-widget-de-categorias_17.html"&gt;Parte III&lt;/a&gt;. Si después de leerlos les queda alguna duda... ¡léanlo otra vez, porque está muy bien explicado!. Bueno, no, pregunten si quieren...&lt;br /&gt;&lt;br /&gt;&lt;div class="footnotes" id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; Si sí que lo hace y yo no lo he conseguido, dejen de leer, por favor. Y díganmelo, porque me he vuelto loco probando hasta decidir (yo solo) que no se puede.&lt;br /&gt;&lt;sup&gt;2&lt;/sup&gt; Evidentemente, hay que emplear alguna palabra que no vayamos a usar en posts que no sean de esa subcategoría.&lt;/div&gt;&lt;br /&gt;&lt;div class="sources"&gt;&lt;a href="http://code.google.com/apis/gdata/reference.html#Queries"&gt;Blogger Data API&lt;/a&gt;. Consultas.&lt;br /&gt;&lt;a href="http://help.blogger.com/bin/topic.py?topic=12449"&gt;Blogger Layout Help&lt;/a&gt;.&lt;/div&gt;&lt;br /&gt;&lt;a class="reltext" onclick="return Mostra('rel')"&gt;Posts relacionados&lt;/a&gt;&lt;br /&gt;&lt;div class="related" id="rel"&gt;&lt;a href="http://civada.blogspot.com/2007/09/seguir-leyendo-2-bobo-tutorial.html"&gt;Cómo hacer un Seguir Leyendo&lt;/a&gt;&lt;br /&gt;&lt;a href="http://civada.blogspot.com/2007/08/1er-bobo-tutorial-ensanchecer-blogger.html"&gt;Ensanchar el blog (ya no se aplica a mi blog)&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150691805752037383-6377168551576619783?l=civada.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://civada.blogspot.com/feeds/6377168551576619783/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1150691805752037383&amp;postID=6377168551576619783" title="16 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/6377168551576619783" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/6377168551576619783" /><link rel="alternate" type="text/html" href="http://civada.blogspot.com/2008/09/crear-subetiquetas-en-blogger.html" title="Crear subetiquetas en Blogger" /><author><name>Delirium</name><uri>http://www.blogger.com/profile/08408043740617685786</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>16</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150691805752037383.post-9078009932835836126</id><published>2008-08-28T12:08:00.003+02:00</published><updated>2008-08-28T16:27:55.497+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Informática" /><title type="text">El fallo en BGP, algo nuevo pero no tanto</title><content type="html">&lt;span style="font-size: 95%;"&gt;Han saltado las alertas. La comunidad informática mundial se enfrenta a la mayor amenaza a la privacidad en Internet. Se ha desvelado un fallo de seguridad que pone en peligro las comunicaciones de todo el tráfico en la red de redes. De hecho esta página que usted está leyendo podría ser falsa y estas palabras no haberlas escrito yo. Es incluso más posible que alguien esté tan sólo fisgoneando todas las páginas que usted pide. Y este es el &lt;a href="http://www.elpais.com/articulo/internet/fallo/peor/temido/elpeputec/20080807elpepunet_7/Tes"&gt;segundo&lt;/a&gt; super fallo desvelado en apenas unos meses.&lt;br /&gt;&lt;br /&gt;Supongo que eso es lo que pensará usted si ha leído las informaciones (la &lt;a href="http://www.elpais.com/articulo/internet/Internet/deja/abierta/puerta/espias/elpeputec/20080827elpepunet_5/Tes"&gt;I&lt;/a&gt; y la &lt;a href="http://www.elpais.com/articulo/internet/protocolo/BGP/elpeputec/20080827elpepunet_9/Tes"&gt;II&lt;/a&gt;) aparecidas en &lt;b&gt;El País&lt;/b&gt; acerca del fallo en el protocolo BGP. No seré demasiado duro juzgando a los articulistas y diré simplemente que no lo han explicado o entendido muy bien. O traducido, porque la cosa viene bastante bien explicada en &lt;a href="http://blog.wired.com/27bstroke6/2008/08/revealed-the-in.html"&gt;Wired&lt;/a&gt; y la información de El País copia sólo la mitad y traduce mal la parte que copia.&lt;br /&gt;&lt;br /&gt;Lo que les cuento en el primer párrafo es totalmente cierto. Pero es que es totalmente cierto incluso sin existir el fallo de seguridad descubierto ahora. En este post, yo, que tengo más espacio que la gente de El País (en eso se les disculpa) les cuento de qué va el fallo BGP y qué supone de nuevo.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="fullpost" style="font-size: 95%;"&gt;En una frase tiene mucha razón el segundo artículo de El País y es que Internet no se diseñó para ser segura. La información que usted solicita y que le llega a su ordenador fluye por los cables visible para todos: como si usted envía una carta en un sobre abierto. En Internet sería un poco complicado leer la carta, porque la información se trocea en pequeños paquetes, pero la idea es la misma: sólo tienes que estar &lt;i&gt;en el lugar adecuado&lt;/i&gt; para recoger la información y husmear.&lt;br /&gt;&lt;br /&gt;Ese tipo de ataques se llaman de hombre en el medio -&lt;i&gt;man in the middle&lt;/i&gt;- y lo han hecho todos los estudiantes de informática en alguna práctica cuando, con un &lt;i&gt;sniffer&lt;/i&gt; de paquetes, se ponen a mirar qué es lo que pasa por la red local a la que están conectados todos los ordenadores del laboratorio. Evidentemente, el hombre en medio puede leer toda la información entre origen y destino siempre que no vaya cifrada. Así que la amenaza no es nada nueva: el fallo BGP consiste en un buen modo de situarse en el lugar adecuado y recibir tráfico para fisgonearlo o incluso modificarlo.&lt;br /&gt;&lt;br /&gt;Ya conté &lt;a href="http://civada.blogspot.com/2007/09/csi-cmo-funciona-internet.html"&gt;cómo funcionaba Internet&lt;/a&gt;, aunque me hicieron falta dos posts y puede que la cosa no quedara muy clara. La idea es que, para llegar de una red de computadores directamente conectados a otra se utilizan dispositivos llamados &lt;b&gt;routers&lt;/b&gt;. Entre dos redes pueden existir varios caminos distintos que pasan por distintos routers. Es necesario que un mensaje que va de una red a otra no permanezca dando saltos sin llegar nunca a su destino. Para ello, los routers seleccionan el mejor camino entre dos redes de entre los muchos que pueden existir. ¿Cómo se ponen de acuerdo?. Pues usando un protocolo (un lenguaje común) que se llama &lt;b&gt;BGP&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;BGP significa &lt;i&gt;Border Gateway Protocol&lt;/i&gt;. Tiene sentido si pensamos en los routers como puertas que están en las fronteras de las redes, decidiendo cuál es el siguiente salto que un mensaje tiene que dar para llegar a su destino. Sin entrar en detalles, los routers deciden a qué siguiente puerta tienen que encaminarlos en base a la información que le proporciona el resto de routers mediante BGP. Pero ¿qué sucede si un router miente?.&lt;br /&gt;&lt;br /&gt;Pues eso es lo que se les ha ocurrido a los chicos investigadores. Que no hay manera de detectar esa situación porque cuando se diseñó el protocolo a nadie se le ocurrió que un router podía mentir. La gracia es que de forma muy sencilla puede mentir para situarse como &lt;i&gt;la mejor puerta por donde pasar para ir a...&lt;/i&gt; y así espiar el tráfico que va a... Podría también eliminar todo el tráfico que por allí pasara (&lt;i&gt;blackhole&lt;/i&gt;), pero entonces se detectaría fácilmente&lt;a href="#fn1"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;. Es más peligroso si modifica ligeramente la información, engañando de este modo a los receptores. Wired comenta que posiblemente este método podría ser usado para espionaje corporativo o militar. Aquí el artículo de El País la caga bien y traduce &lt;i&gt;conceivably&lt;/i&gt; (posiblemente) por &lt;i&gt;fue concebido&lt;/i&gt; y nos sale con que 'el fallo' fue concebido para ser aprovechado por el espionaje militar. Confunde ademas posibilidad (&lt;i&gt;could&lt;/i&gt;) con pasado. Toma ya&lt;a href="#fn1"&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Por supuesto, la solución no pasa por gastar firewalls, como indica el segundo artículo de El País. Ni por tener cuidado por donde se navega, ni tener antivirus ni saber algo del SO&lt;a href="#fn1"&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt;. Posiblemente la solución consistirá en modificar el protocolo BGP de una forma complicada. En realidad, la auténtica solución pasaría por cifrar todas las comunicaciones que realizamos a través Internet. Las técnicas de cifrado en Internet &lt;a href="http://civada.blogspot.com/2008/03/csi-xii-criptografa-y-cifrado-de-datos.html"&gt;son conocidas&lt;/a&gt;, están bien estudiadas y garantizan la confidencialidad y seguridad durante largo tiempo. Con la implicación de los ISPs (proveedores de servicios, como Telefónica) no debería ser muy difícil conseguir esto.&lt;br /&gt;&lt;br /&gt;El auténtico problema de la privacidad y seguridad en Internet es que no le interesa a nadie excepto a los usuarios. Y a los que menos interesa es a los Gobiernos, quienes, siempre invocando nuestra propia seguridad, desean tener la oportunidad de fisgonear e interceptar todo tipo de comunicaciones. Y claro, siendo así, difícil es que se implante, ¿no?.&lt;br /&gt;&lt;br /&gt;&lt;div class="footnotes" id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; De hecho, &lt;a href="http://news.bbc.co.uk/1/hi/technology/7262071.stm"&gt;eso fue lo que pasó&lt;/a&gt; cuando el proveedor de servicios de Internet (quienes suelen mantener los routers) de Pakistan  decidió bloquear el tráfico a Youtube de ese modo. El problema fue que  routers de países adyacentes fueron así confundidos y el tráfico dirigido a Youtube nunca llegaba a su destino: caía en el agujero de Pakistan.&lt;br /&gt;&lt;sup&gt;2&lt;/sup&gt; ¡ALT1040 no solo se lo cree sino que &lt;a href="http://alt1040.com/2008/08/el-agujero-de-seguridad-mas-importante-de-internet/"&gt;añade literatura&lt;/a&gt;!&lt;br /&gt;&lt;sup&gt;3&lt;/sup&gt; Todas ellas prácticas muy recomendadas. Yo añado dos: evite Internet Explorer y bloquee los scripts de las páginas (en Firefox se puede hacer con &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/722"&gt;No-Script&lt;/a&gt;).&lt;/div&gt;&lt;br /&gt;&lt;div class="sources"&gt;&lt;a href="http://blog.wired.com/27bstroke6/2008/08/revealed-the-in.html"&gt;El agujero de seguridad más grande de Internet&lt;/a&gt;. Wired&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/IP_hijacking"&gt;IP hijacking&lt;/a&gt; (Wikipedia inglesa).&lt;br /&gt;&lt;a href="http://www.kriptopolis.org/revelan-mayor-agujero-seguridad-internet"&gt;Kriptopolis&lt;/a&gt; lo cuenta con más detalle y muy bien.&lt;/div&gt;&lt;br /&gt;&lt;a class="reltext" onclick="return Mostra('rel')"&gt;Posts relacionados&lt;/a&gt;&lt;br /&gt;&lt;div class="related" id="rel"&gt;&lt;a href="http://civada.blogspot.com/2007/09/csi-cmo-funciona-internet.html"&gt;Como funciona Internet (I)&lt;/a&gt;&lt;br /&gt;&lt;a href="http://civada.blogspot.com/2007/10/csi-vii-cmo-funciona-internet-ii.html"&gt;Como funciona Internet (II)&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150691805752037383-9078009932835836126?l=civada.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://civada.blogspot.com/feeds/9078009932835836126/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1150691805752037383&amp;postID=9078009932835836126" title="3 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/9078009932835836126" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/9078009932835836126" /><link rel="alternate" type="text/html" href="http://civada.blogspot.com/2008/08/el-fallo-en-bgp-algo-nuevo-pero-no.html" title="El fallo en BGP, algo nuevo pero no tanto" /><author><name>Delirium</name><uri>http://www.blogger.com/profile/08408043740617685786</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150691805752037383.post-1620601342771109456</id><published>2008-07-09T17:29:00.002+02:00</published><updated>2008-07-13T11:23:56.675+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Informática" /><title type="text">El problema de los generales bizantinos</title><content type="html">&lt;span style="font-size:95%;"&gt;Sitúese.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;Está usted en el campo de batalla arrasado, y el viento ondea sus banderas blasonadas, que amenazan la ciudad rebelde, por fin sitiada. Sin embargo, las torturas a las que ha sometido a los infieles no han minado el espíritu enemigo y ningún prisionero ha revelado la cantidad de hombres que guarda la ciudad amurallada. Usted tiene un ejército numeroso, sí, pero las lineas de comunicación y aprovisionamiento han sido destruidas: no podrá mantener demasiado el sitio sobre la ciudad. Urge tomar una decisión sobre el curso de la batalla y, como general que es, deberá consultar con el resto de mandos. La opciones son pocas: atacar todos a la vez o retirarse.&lt;br /&gt;&lt;br /&gt;Pero hay un gran problema: sospecha usted que el enemigo se ha infiltrado en sus filas hasta tal punto que es posible que algunos de sus compañeros generales se encuentren, secretamente, sirviendo al enemigo. &lt;b&gt;¡Hay traidores entre los generales!&lt;/b&gt;. Usted sospecha de un par de ellos pero sólo si es capaz de ponerse de acuerdo con otros generales leales en su acusación podrá desenmascarar a los traidores. No puede usted pensar mucho, sus hombres son bravos pero la lealtad se resiente con el estómago vacío. Sólo podrá derrotar al enemigo si ataca con todas las fuerzas de los generales leales así que... ¿podrá usted descubrir a los traidores?. ¿Será capaz usted de poner de acuerdo a los &lt;i&gt;generales bizantinos&lt;/i&gt;?.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="fullpost"  style="font-size:95%;"&gt;El problema de los generales bizantinos fue formulado de esta forma (con menos literatura) por &lt;a href="http://en.wikipedia.org/wiki/Leslie_Lamport"&gt;Leslie Lamport&lt;/a&gt;&lt;a href="#fn1"&gt;&lt;sup&gt;1,2&lt;/sup&gt;&lt;/a&gt;, uno de los grandes de la informática, en 1982. Desde entonces es uno de los clásicos en la teoría de sistemas distribuidos. ¿Y por qué?. Pues veamos.&lt;br /&gt;&lt;br /&gt;Piense que en vez de tener usted un conjunto de generales bizantinos tiene usted un conjunto de computadores distribuidos, llevando a cabo una tarea común. Por ejemplo, una transacción bancaria o la monitorización de la ruta de un avión. Eso suena más informático.&lt;br /&gt;&lt;br /&gt;Supongamos que uno de los computadores del sistema deja de funcionar. Hace &lt;i&gt;plof&lt;/i&gt; y ya está. No responde a los mensajes del resto, ni ofrece resultados: nada. ¿Como podemos saber que ha fallado? Pues muy fácil, como no hace nada ni envía los mensajes que tiene que enviar ni responde a las llamadas, deducimos que ha fallado. Lo más sencillo entonces es reemplazarlo: que otro haga la misma tarea que realizaba. Si un componente 'se muere' de este modo, decimos que ha fallado &lt;i&gt;en modo crash&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Ahora el mismo componente falla, pero en vez de no hacer nada siempre realiza su tarea &lt;i&gt;más tarde de lo que debería&lt;/i&gt;. ¿Cómo nos damos cuenta de este fallo?. Pues tan sólo nos es necesario poner en marcha un reloj cuando debería iniciarse. Si, transcurrido el tiempo determinado, el computador o componente no ha ofrecido un resultado, sabemos que está fallando. Y podemos reemplazarlo por otro, como antes. En este caso decimos que el componente falla &lt;i&gt;en modo performance&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Un pasito más. Supongamos que un elemento ofrece resultados dentro del tiempo establecido pero... estos resultados son siempre incorrectos. Aquí se complica la cosa. ¿Cómo sabemos si falla?. Podemos, por ejemplo, poner dos procesadores a hacer la misma tarea y comparar los resultados pero aún así si estos no concuerdan, ¿cómo saber cuáles son los buenos y cuales no?. En este caso necesitamos tres componentes para tolerar el fallo de uno. Y, en general, &lt;b&gt;2n+1&lt;/b&gt; para tolerar &lt;b&gt;n&lt;/b&gt; fallos. Estos fallos se llaman &lt;i&gt;response&lt;/i&gt;. Y los sistemas con tres componentes y un comparador se llaman &lt;b&gt;TMR&lt;/b&gt; (&lt;i&gt;triple modular redundancy&lt;/i&gt;).&lt;br /&gt;&lt;br /&gt;¿Se han fijado cómo cada vez necesitamos más cosas para detectar el fallo?&lt;br /&gt;&lt;br /&gt;Y ahora vamos a lo bueno. Supongamos que un componente tiene un comportamiento errático y que, a veces ofrece una respuesta correcta y a veces no. Supongamos que, en las votaciones para detectar la respuesta correcta, este computador acusa a otros de ser los erróneos: a uno le dice una cosa, a otro otra distinta. Actúa como un traidor. Como un traidor bizantino.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;Está usted de nuevo en el campo de batalla. Y ya tiene su decisión, atacar o retirarse, que debe transmitir al resto de generales. Los generales leales no se equivocarán, y si creen que atacar es la mejor opción, arrasarán al enemigo. Sin embargo puede que los traidores consigan que decidamos retirarnos. Por otro lado, aunque una mayoría de generales leales haya decidido no atacar, es posible que con el voto de los traidores se fuerce el asalto, cayendo en una trampa mortal.&lt;br /&gt;&lt;br /&gt;&lt;a title="El problema de los tres generales"&gt;&lt;img style="float:right; margin:0 0 15px 15px;" src="http://img502.imageshack.us/img502/344/3generalesun1.png" border="0" alt="" /&gt;&lt;/a&gt;Usted razona: si sólo hubiera tres generales y uno fuera el traidor... ¿podríamos ponernos de acuerdo la mayoría? Supongamos que yo -&lt;a href="http://en.wikipedia.org/wiki/Apocapes"&gt;Apocapes&lt;/a&gt;- envío a ambos la orden de atacar. Los generales &lt;a href="http://en.wikipedia.org/wiki/Belisarius"&gt;Belisarius&lt;/a&gt; y &lt;a href="http://en.wikipedia.org/wiki/Comentiolus"&gt;Comentiolus&lt;/a&gt; reciben mi orden, bien. Y sin embargo, el traidor Belisarius informa a Comentiolus de que mi orden ha sido la de retirada. ¿Que pensará Comentiolus? Pues que, o bien Belisarius es el traidor, como de hecho sucede... ¡o bien que el traidor soy yo, el insigne general Apocapes!. Las dos situaciones serían indistinguibles a los ojos de Comentiolus.&lt;br /&gt;&lt;br /&gt;Así que, a pesar de ser mayoría los generales leales (de 2 a 1), no podremos llegar nunca a un acuerdo, pues no sabremos de quien fiarnos. Si dispusiéramos de cartas firmadas... podría enviar cada una de ellas al resto de generales y luego estos intercambiar las mismas. Sin embargo &lt;i&gt;cada general sólo puede controlar lo que transmite, no lo que intercambia el resto&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Entonces ¿y si somos cuatro y uno infiel?. Entonces sí que será posible, puesto que &lt;a href="http://en.wikipedia.org/wiki/Droctulf"&gt;Droctulf&lt;/a&gt;, el cuarto general, podrá confirmar que yo di la orden de atacar. ¿Será posible que con más del triple de generales leales podamos acordar una solución?&lt;br /&gt;&lt;br /&gt;Por supuesto, la suposición a usted no le vale. Necesita la prueba matemática de cuántos generales son necesarios para llegar a un acuerdo con &lt;b&gt;t&lt;/b&gt; generales traidores infiltrados. Pero eso aquí no aparecerá: digamos que simplemente imagina grupos de &lt;b&gt;3t&lt;/b&gt; o menos generales generales (albaneses) que alcanzan el acuerdo: consigue reducir el problema al de los tres generales encontrando por tanto una contradicción. &lt;i&gt;Se requieren &lt;b&gt;3t + 1&lt;/b&gt; generales leales para acordar una solución&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Las banderas se hinchen con renovada fuerza en el campamento. Los generales que rodean la ciudad son 8 y, si el Imperio Bizantino aún conserva parte de su gloria, los traidores serán dos de ellos. Ahora sabe usted que sin duda podrán alcanzar la mejor decisión.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;¿Y qué tiene que ver esto con la informática?. Pues mucho. Si usted no es capaz de evitar los &lt;b&gt;fallos bizantinos&lt;/b&gt; en sus programas o componentes que actúan de manera distribuida, sepa que cualquier sistema de decisión requerirá de al menos MAS DEL TRIPLE de componentes que actúen correctamente que los que no&lt;a href="#fn1"&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Y eso es vital en &lt;b&gt;Tolerancia a Fallos&lt;/b&gt;: los sistemas están diseñados para que cualquier tipo de fallo pueda convertirse en uno tipo &lt;i&gt;crash&lt;/i&gt;. Aunque se necesite aumentar la circuitería o software de detección, los fallos &lt;i&gt;crash&lt;/i&gt; (u &lt;i&gt;omission&lt;/i&gt;) -semántica débil de fallo- son por lo general más fáciles de tratar.&lt;br /&gt;&lt;br /&gt;Y por eso se le suele dar muerte  a los traidores. Es la solución mas ingenieril.&lt;br /&gt;&lt;br /&gt;&lt;div class="footnotes" id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; El problema de los generales es más antiguo, pero la generalización de Lamport es la más conocida.&lt;br /&gt;&lt;sup&gt;2&lt;/sup&gt; ¿Sabían que Leslie Lamport también creó &lt;a href="http://es.wikipedia.org/wiki/LaTeX"&gt;LaTeX&lt;/a&gt; (&lt;i&gt;Lamport TeX&lt;/i&gt;)?&lt;br /&gt;&lt;sup&gt;3&lt;/sup&gt; Siempre que las comunicaciones sean como las descritas, esto es, que un miembro no puede garantizar que e estado que de él transmiten los otros es cierto.&lt;/div&gt;&lt;br /&gt;&lt;div class="sources"&gt;&lt;small&gt;LESLIE LAMPORT, ROBERT SHOSTAK, and MARSHALL PEASE&lt;/small&gt;. &lt;i&gt;The Byzantine Generals Problem&lt;/i&gt;. ACM Transactions on Programming Languages and Systems, Vol. 4, No. 3, July 1982, pp 382-401. (&lt;a href="http://research.microsoft.com/users/lamport/pubs/byz.pdf"&gt;enlace&lt;/a&gt;)&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Category:Byzantine_generals"&gt;Lista de Generales Bizantinos&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;a class="reltext" onclick="return Mostra('rel')"&gt;Posts relacionados&lt;/a&gt;&lt;br /&gt;&lt;div class="related" id="rel"&gt;&lt;a href="http://civada.blogspot.com/2007/06/el-trabajo-de-aitor-menta-i.html"&gt;El trabajo de Aitor Menta (sobre tolerancia a fallos)&lt;/a&gt;&lt;br /&gt;&lt;a href="http://civada.blogspot.com/2008/03/csi-xi-cdigos-que-corrigen-errores.html"&gt;Códigos correctores de errores&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150691805752037383-1620601342771109456?l=civada.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://civada.blogspot.com/feeds/1620601342771109456/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1150691805752037383&amp;postID=1620601342771109456" title="7 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/1620601342771109456" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/1620601342771109456" /><link rel="alternate" type="text/html" href="http://civada.blogspot.com/2008/07/el-problema-de-los-generales-bizantinos.html" title="El problema de los generales bizantinos" /><author><name>Delirium</name><uri>http://www.blogger.com/profile/08408043740617685786</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150691805752037383.post-3618914742857504258</id><published>2008-05-30T19:58:00.001+02:00</published><updated>2008-05-30T20:00:54.745+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Informática" /><title type="text">CSI XIII: El lenguaje de las máquinas</title><content type="html">&lt;span style="font-size:95;"&gt;Muchas personas han oído hablar alguna vez de &lt;i&gt;lenguajes de programación&lt;/i&gt;. Se intuye que los lenguajes de programación sirven para decir a un computador qué instrucciones debe ejecutar para llevar a cabo determinada tarea. Claro, que eso es bastante complicado de realizar. Si nosotros pudiésemos hablar al ordenador le diríamos: "conéctate a Internet" o "Inserta al nuevo cliente en la base de datos". Bueno, eso podemos, podemos hablar al computador todo lo que queramos. El problema es que dudo mucho que entienda nuestro lenguaje.&lt;br /&gt;&lt;br /&gt;¿Qué lenguaje entiende un computador?. Según el párrafo anterior la respuesta sería: lenguajes de programación. Otro, quizá, más versado, diga: "el de unos y ceros". En realidad es una pregunta trampa, porque el concepto de lenguaje es una abstracción humana. Si llamamos lenguaje al conjunto de señales que emitimos y recibimos para comunicar algo, entonces el lenguaje de las máquina sería el de las señales eléctricas de tensión que según sus niveles, llamamos 0 lógico o 1 lógico. Si en cambio llamamos lenguaje a una construcción de símbolos (o palabras) gobernadas por una gramática, entonces la respuesta está más cerca de la primera.&lt;br /&gt;&lt;br /&gt;No sólo los computadores como su PC entienden lenguajes: muchas máquinas, robots de procesos industriales o ascensores entienden algún tipo de lenguaje que los hace funcionar: qué características tiene ese lenguaje es lo que voy a intentar explicar en los siguientes posts.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="fullpost"  style="font-size:95;"&gt;[Antes de continuar aviso que me estoy metiendo en camisa de once varas, porque éste no es, ni mucho menos, mi campo natural. Avisado queda el lector avanzado]&lt;br /&gt;&lt;br /&gt;Nos ayudará a entender qué lenguajes entienden las máquinas una pequeña revisión histórica. La programación más antigua de una máquina conocida es la de los &lt;a href="http://es.wikipedia.org/wiki/Telar_de_Jacquard"&gt;telares de de Jacqard&lt;/a&gt; (1801), donde una tarjeta perforada controlaba el movimiento de las agujas. Aquí, por supuesto, no había computación alguna sino que los agujeros en las tarjetas permitían ciertos movimientos. Otras máquinas utilizaron este sistema y cuando nacieron los primeros computadores, basados en dispositivos electromecánicos, la &lt;a href="http://en.wikipedia.org/wiki/Punched_card"&gt;tarjeta perforada&lt;/a&gt; se empleó para asignarles instrucciones y entrada de datos.&lt;br /&gt;&lt;br /&gt;Durante la IIGM, por ejemplo, los grandes computadores se utilizaban para los complicados cálculos de trayectorias. Richard Feynman, en los laboratorios de Los Álamos estaba encargado de la sección informática. En el libro &lt;i&gt;¿Está usted de broma, sr. Feynman?&lt;/i&gt; narra cómo los ingenieros debían escribir los programas en tarjetas y, secuencialmente, introducirlas en la máquina para que ésta realizara su trabajo. Si te equivocas en el orden las has fastidiado&lt;a href="#fn1"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;. Aquí hay que entender que un computador es un procesador de instrucciones, nada más. Y las instrucciones que puede ejecutar son específicas de cada chip o circuito impreso. &lt;br /&gt;&lt;br /&gt;Las tarjetas representaban en ocasiones códigos binarios (ceros y unos). Cada código identifica una instrucción o operación que puede hacer la máquina. Las operaciones que puede hacer un procesador son terriblemente sencillas: lee una instrucción de la tarjeta, multiplica un dato por otro, escribe sobre una posición de memoria... muy poco más, no se crean. Al lenguaje de unos y ceros se le llama &lt;b&gt;código máquina&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;Se pueden imaginar lo complicado que era programar de este modo un computador. Pero pronto, en la década de 1950 aparecieron una serie de códigos mnemónicos para identificar cada instrucción. Estos códigos consistían en unas pocas letras, que representaban el nombre de la instrucción seguidas de los operandos propios de cada una de ellas. Por ejemplo:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;" &gt;ADD A, #03h&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;significa, una vez traducida al código máquina:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;" &gt;00100100 00000011&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Y representa la instrucción que dice que hay que sumar un número (3) al registro acumulador, que guarda los resultados de la unidad sumadora. Como ven, se trata de un avance significativo, porque programar se convierte en algo mucho más sencillo. Es muy fácil recordar los códigos de un procesador y más difícil equivocarnos. Por ejemplo, si escribo &lt;b&gt;AFD A, #03h&lt;/b&gt;, el programa que traduce estos códigos a lenguaje máquina se quejará, porque no existe ningún código llamado &lt;b&gt;AFD&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a title="Apu intentando hablar con el computador"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right;" src="http://img165.imageshack.us/img165/6444/apulenguajeszm3.png" alt="" border="0" /&gt;&lt;/a&gt;El programa que traduce estos códigos al lenguaje máquina se llama &lt;b&gt;ensamblador&lt;/b&gt;&lt;a href="http://www.blogger.com/post-edit.g?blogID=5372298608033125113&amp;amp;postID=1057237860971619277#fn1"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;. Y también se llama así al lenguaje generado por estos códigos. El  paso de lenguaje máquina a lenguaje ensamblador produjo la llamada &lt;a href="http://en.wikipedia.org/wiki/Second-generation_programming_language"&gt;segunda generación de lenguajes&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Pero el ensamblador tiene algunas pegas: la operación que hemos visto, por ejemplo, pertenece al juego de instrucciones del procesador 8051 y, por tanto, no sirve para ningún otro procesador que no sea compatible con éste. Esto significa que un mismo programa no nos sirve para distintas máquinas y que cada vez que una compañía de chips cambie el juego de instrucciones del procesador, necesitaremos reescribir todos los programas que tenemos (por eso se intenta cambiar pocas veces el juego de instrucciones y cuando se hace es para ampliar, pocas veces para quitar).&lt;br /&gt;&lt;br /&gt;Efectivamente, el lenguaje ensamblador está demasiado pegado a la máquina: para programar bien tienes que conocer detalles de la &lt;i&gt;arquitectura del procesador&lt;/i&gt;. Por ejemplo, si no sabes cómo funciona ni donde está el registro acumulador del procesador, difícilmente sabrás cómo hacer una suma, por más que exista una instrucción llamada 'ADD'.&lt;br /&gt;&lt;br /&gt;Era necesario "independizar" de alguna manera el código que escribíamos en cierto lenguaje del modo en que el procesador actúa. Y por cierto, estamos hablando de 'lenguaje', pero está claro que una secuencia de estos códigos se parece a todo menos a un lenguaje tal y como lo hablamos o leemos.&lt;br /&gt;&lt;br /&gt;Sin embargo, imaginen poder decir a cualquier procesador algo así como:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;" &gt;si nuevo_nombre es_igual_a Ramon&lt;br /&gt;entonces dime "Hola Ramon"&lt;br /&gt;y_si_no dime "No te conozco"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Pues bien hay maneras de crear lenguajes de esta manera: a la nueva generación de lenguajes que pudo hacer eso: abstraerse de la máquina donde son ejecutados se les llamó &lt;i&gt;lenguajes de tercera generación&lt;/i&gt; y los primeros surgieron hacia los años 60. Los lenguajes de tercera generación se separan tanto del computador que están más cerca del ser humano que de la máquina: por su nivel de abstracción se llaman &lt;b&gt;lenguajes de alto nivel&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;Y en el siguiente capítulo veremos cómo se puede conseguir hacer eso.&lt;br /&gt;&lt;br /&gt;&lt;div class="footnotes" id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; Como le pasó al pobre &lt;a href="http://en.wikipedia.org/wiki/Punched_card#Ongoing_cultural_impact_of_punch_cards"&gt;Apu&lt;/a&gt;, el creador del primer programa para jugar al tres en raya. Bart desordenó sus tarjetas perforadas.&lt;br /&gt;&lt;sup&gt;2&lt;/sup&gt; Quizá se pregunten cómo se ha escrito el propio programa ensamblador. Pues los primeros de ellos, claro está, se escribieron en lenguaje máquina.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="sources"&gt;Por si les interesa: &lt;a href="http://www.win.tue.nl/~aeb/comp/8051/set8051.html"&gt;aquí&lt;/a&gt; el juego de instrucciones del 8051&lt;/div&gt;&lt;br /&gt;&lt;a class="reltext" onclick="return Mostra('rel')"&gt;Posts relacionados&lt;/a&gt;&lt;br /&gt;&lt;div class="related" id="rel"&gt;&lt;a href=""&gt;Aún no hay relacionados...&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150691805752037383-3618914742857504258?l=civada.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://civada.blogspot.com/feeds/3618914742857504258/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1150691805752037383&amp;postID=3618914742857504258" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/3618914742857504258" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/3618914742857504258" /><link rel="alternate" type="text/html" href="http://civada.blogspot.com/2008/05/csi-xiii-el-lenguaje-de-las-mquinas.html" title="CSI XIII: El lenguaje de las máquinas" /><author><name>Delirium</name><uri>http://www.blogger.com/profile/08408043740617685786</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150691805752037383.post-6251768019374722506</id><published>2008-04-30T19:14:00.001+02:00</published><updated>2008-07-10T10:26:05.639+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Informática" /><title type="text">El Nilo, Internet, y los fractales</title><content type="html">&lt;span style="font-size: 95%;"&gt;Y el precio del algodón, claro, aunque no me cabía en el título. Pero vayamos por partes.&lt;br /&gt;&lt;br /&gt;&lt;a title="Sí, esto es una presa en el Nilo, qué pasa"&gt;&lt;img style="float:right; margin:0 0 10px 10px;" src="http://img53.imageshack.us/img53/1858/presajj6.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;a href="http://en.wikipedia.org/wiki/Harold_Edwin_Hurst"&gt;Harold Edwin Hurst&lt;/a&gt; nació en 1880, cerca de Leicester. De origen humilde, muy pronto destacó en sus estudios, obteniendo  una beca que le permitió estudiar en Oxford. Allí se graduó con méritos en Física, sin apenas formación matemática previa. En 1906 le surgió la oportunidad de viajar al aún británico Egipto y Hurst aceptó. En ese país se dedicaría a la investigación durante más de 60 años, por encima de los cambios políticos que sucedieron a la descolonización.&lt;br /&gt;&lt;br /&gt;Aunque se ocupó de diversas tareas en sus primeros años (relacionadas con la astronomía o geología), pronto perseveró en el estudio de la meteorología e hidrología. En 1915 Hurst se convirtió en el director del Departamento Físico de Obras Públicas. Y a este departamento le correspondió el problema de domesticar el poderoso río Nilo a los intereses de las industrias y campos a sus orillas. El sistema utilizado para ello, era, claro está, a través de embalses.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="fullpost" style="font-size: 95%;"&gt;Analicemos el problema (simplificado): supongamos que lo que queremos es determinar cuál debe ser la altura mínima de una presa o paredes de los embalses (&lt;b&gt;Figura 1&lt;/b&gt;). Para ello, idealmente, sólo necesitamos conocer cuál es la capacidad y forma del embalse, la tasa a la que se puede desalojar el agua del mismo y el caudal máximo que llega a aportar el río a su entrada. Y claro, de las tres cosas, lo único impredecible es esto último. ¿O no?. Determinar ese nivel fue la tarea a la que se enfrentó Hurst.&lt;br /&gt;&lt;br /&gt;Por suerte el Nilo es un río histórico, y sus niveles han sido estudiados a lo largo de los siglos por diferentes civilizaciones. Hurst no solo se aplicó en obtener detalladas mediciones del volumen del Nilo en distintos instantes de su época (correlacionados con muchas otras variables), sino que recopiló con tesón los registros históricos que le darían una visión de conjunto. &lt;br /&gt;&lt;br /&gt;Hurst se dio cuenta, que, a pesar de la apariencia irregular de las mediciones, seguían cierto patrón agrupado en épocas de sequía e inundaciones. Y lo que es aún más raro, &lt;i&gt;ese patrón irregular se repetía a distintos niveles&lt;/i&gt;. Dicho de otra manera: la serie de datos observada a corta distancia -intervalos de días- "se parece" a la serie observada a lo largo de años. &lt;br /&gt;&lt;br /&gt;El problema es que entonces no existía ningún modelo matemático que expresase esta idea, así que Hurst creó el suyo. Sin entrar en detalles (ya no tengo mucha soltura matemática), descubrió que la relación entre las medidas podía ajustarse mediante un parámetro de una ecuación, que relaciona la varianza de las muestras agrupada. Si el valor de este coeficiente -&lt;b&gt;coeficiente de Hurst&lt;/b&gt;- es 0.5, se considera que el proceso es completamente aleatorio. Si en cambio el valor de éste se encuentra entre 0.5 y 1, se dice que que el proceso sigue el mismo patrón a distintas escalas: se convierte en un &lt;a href="http://en.wikipedia.org/wiki/Self_similar"&gt;proceso autosimilar&lt;/a&gt;. En concreto, para el Nilo, este valor era de 0.72.&lt;br /&gt;&lt;br /&gt;Los científicos acogieron con escepticismo esta idea. Más que nada porque Hurst había dado con un ajuste, pero no había ofrecido lo más interesante: el por qué sucede de este modo y no de otro cualquiera. Pero tras divulgarse en los años 50 sus resultados, muchos científicos (y de muchos otros campos) midieron valores de 0.7 para fenómenos completamente distintos de los hidrológicos.&lt;br /&gt;&lt;br /&gt;Uno de estos científicos era matemático y se llama &lt;a href="http://es.wikipedia.org/wiki/Beno%C3%AEt_Mandelbrot"&gt;Benoît Mandelbrot&lt;/a&gt;. Estudiaba la economía. Tras publicar un estudio sobre las fluctuaciones del precio del algodón, un amigo le advirtió de las similaridades con los resultados de Hurst. Mandelbrot estudió entonces en profundidad el trabajo de Hurst y concluyó que podía aplicarse a las finanzas, donde las fluctuaciones a largo plazo podían ser previstas gracias al análisis de Hurst. Mandelbrot, de origen judío, acuño dos términos para describir las variaciones en un proceso a larga escala:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;El efecto José&lt;/b&gt; nos dice que las fluctuaciones de los valores de un proceso a lo largo del tiempo tienden a ser parte de un patrón más amplio. Se denomina de este modo a causa de la predicción que José lanzó sobre Egipto a través de los sueños del Faraón: que a siete años de abundancia seguirían siete de hambruna.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Aconteció que pasados dos años tuvo Faraón un sueño. Le parecía que estaba junto al río; y que del río subían siete vacas, hermosas a la vista, y muy gordas, y pacían en el prado. Y que tras ellas subían del río otras siete vacas de feo aspecto y enjutas de carne, y se pararon cerca de las vacas hermosas a la orilla del río; y que las vacas de feo aspecto y enjutas de carne devoraban a las siete vacas hermosas y muy gordas. Y despertó Faraón.&lt;/blockquote&gt;Genesis 41.1-4&lt;br /&gt;&lt;br /&gt;&lt;b&gt;El efecto Noé&lt;/b&gt; nos dice que, además, cuando se producen los cambios o fluctuaciones, éstas tienden a ser abruptas. Vamos, que de normal llueve poco y con regularidad, pero, de vez en cuando, cae la de Dios.&lt;br /&gt;&lt;br /&gt;Los &lt;b&gt;procesos autosimilares&lt;/b&gt; se han estudiado con tesón desde entonces. El propio Mandelbrot se convirtió años más tarde en el famoso padre de los &lt;b&gt;fractales&lt;/b&gt;, donde la relación entre estos y los primeros es evidente. Hurst siguió estudiando el Nilo hasta sus últimos días y murió en 1978. Pero, ¿qué tiene que ver &lt;b&gt;Internet&lt;/b&gt; con todo esto?.&lt;br /&gt;&lt;br /&gt;&lt;a  title="Un elemento de proceso se puede representar mediante el modelo de colas" &gt;&lt;img style="float:right; margin:0 0 10px 10px;" src="http://img53.imageshack.us/img53/3530/colaprocesocd3.png" border="0" alt="" /&gt;&lt;/a&gt;Supongamos que un dispositivo de red debe encaminar flujos de información de muchos orígenes a través de una linea (&lt;b&gt;Figura 2&lt;/b&gt;). Este dispositivo debe poseer los suficientes recursos para que no se pierda información, esto es, no se desborde. Claro, que siendo ingenieros nos interesa poner lo mínimo posible para que funcione bien. Por tanto, tenemos que calcular con precisión el tamaño de la memoria (llamada &lt;i&gt;buffer&lt;/i&gt;) a a la entrada del dispositivo... ¿Les suena este problema?.&lt;br /&gt;&lt;br /&gt;Hasta la década de los 90 se creía que las llegadas a un sistema o dispositivo en Internet (tales como un servidor o un router) seguían una &lt;a href="http://es.wikipedia.org/wiki/Distribuci%C3%B3n_de_Poisson"&gt;distribución de Poisson&lt;/a&gt;. Pero entonces varios artículos y estudios empíricos (&lt;a href="http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?arnumber=282603"&gt;Leland et al&lt;/a&gt;) demostraron que el tráfico de red seguía un patrón autosimilar (o fractal). Por tanto, se podían aplicar todos los análisis realizados en otros campos al diseño de &lt;i&gt;bufferes&lt;/i&gt; y asignación de recursos en la red.&lt;br /&gt;&lt;br /&gt;La imagen muestra la carga real soportada por un servidor web de tamaño mediano y varios detalles de la misma. El parámetro Hurst estimado para ella es de...&lt;br /&gt;&lt;br /&gt;&lt;a title="Carga de un servidor web en bytes a lo largo del día"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;" src="http://img167.imageshack.us/img167/1061/carga2qq3.gif" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Pero, y pasemos ahora de ingenieros a científicos, ¿por qué el tráfico de la red sigue un patrón autosimilar?. Bien, para eso también hay explicaciones propuestas. Se ha demostrado que la agregación de &lt;b&gt;tráficos ON/OFF&lt;/b&gt; genera un patrón autosimilar. Tráfico ON/OFF significa, por ejemplo, que pido una página y me paro un poco. Al poco pido otra página y paro. Agregado significa que si mi hermano está navegando, y mi vecino y sus primos y todas esas peticiones van al mismo servidor, ese tráfico ON/OFF se suma en el destinatario. Pues bien, si el tráfico ON/OFF sigue cierta distribución (secuencia de paradas y peticiones), entonces el agregado resulta autosimilar.&lt;br /&gt;&lt;br /&gt;La gracia es que el tamaño de los objetos que residen en la web (paginas, imágenes, archivos...) actúa sobre el tráfico de un modo parecido al descrito. En la web hay una gran cantidad de objetos muy pequeños que actúan como zonas OFF (poco tráfico) cuando los solicitamos. Pero también hay unos pocos objetos muy pesados que generan mucho tráfico (&lt;i&gt;zonas ON&lt;/i&gt;) al transferirse. Si sumamos el tráfico de 10 personas con patrones de tráfico ON/OFF obtenemos un patrón de tráfico autosimilar, esto es: su coeficiente Hurst es sensiblemente mayor a 0.5.&lt;br /&gt;&lt;br /&gt;No me dirán que no es interesante, ¿no?&lt;br /&gt;&lt;br /&gt;&lt;div class="sources"&gt;Apuntes de clase&lt;br /&gt;&lt;a href="http://www.safehaven.com/article-2729.htm"&gt;Safe Heaven&lt;/a&gt; Sobre el estudo de Hurst y Mandelbrot.&lt;br /&gt;&lt;a href="http://www.cig.ensmp.fr/~iahs/hsj/240/hysj_24_04_0539.pdf"&gt;Hurst obituary&lt;/a&gt;. Vida de Hurst.&lt;br /&gt;El análisis de carga se ha realizado a través del análisis de logs de un servidor mediano. El cálculo estimado del coeficiente de Hurst se ha realizado mediante el programa &lt;a href="http://www.cs.ucr.edu/~tkarag/Selfis/Selfis.html"&gt;Selfis&lt;/a&gt;.&lt;/div&gt;&lt;br /&gt;&lt;a class="reltext" onclick="return Mostra('rel')"&gt;Posts relacionados&lt;/a&gt;&lt;br /&gt;&lt;div class="related" id="rel"&gt;&lt;a href="http://civada.blogspot.com/2007/09/csi-cmo-funciona-internet.html"&gt;Como funciona Internet 1&lt;/a&gt;&lt;br /&gt;&lt;a href="http://civada.blogspot.com/2007/10/csi-vii-cmo-funciona-internet-ii.html"&gt;Como funciona Internet 2&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150691805752037383-6251768019374722506?l=civada.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://civada.blogspot.com/feeds/6251768019374722506/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1150691805752037383&amp;postID=6251768019374722506" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/6251768019374722506" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/6251768019374722506" /><link rel="alternate" type="text/html" href="http://civada.blogspot.com/2008/04/el-nilo-internet-y-los-fractales.html" title="El Nilo, Internet, y los fractales" /><author><name>Delirium</name><uri>http://www.blogger.com/profile/08408043740617685786</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150691805752037383.post-1905002930285688597</id><published>2008-03-29T13:07:00.000+01:00</published><updated>2008-03-29T13:09:28.400+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Informática" /><title type="text">CSI XII: Criptografía y cifrado de datos</title><content type="html">&lt;span style="font-size:95;"&gt;Bueno, en los últimos posts de Cosas que Sí se dan en Informática hemos tratado (y bastante) el tema de la &lt;i&gt;codificación&lt;/i&gt;, que no es más que utilizar otra representación de los datos con algún motivo. Hoy me voy a plantar y os presento el último post dedicado a este tema: luego pasaremos a otra cosa completamente diferente. Pero es que hablando de codificación de la información no quería dejar sin tratar uno de los temas más interesantes y actuales: la &lt;b&gt;encriptación de datos&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;Efectivamente, &lt;i&gt;encriptar&lt;/i&gt; información consiste en transformarla siguiendo unas reglas o algoritmo. Cuando hacemos esto es, &lt;i&gt;por lo general&lt;/i&gt;, porque no nos interesa que todo el mundo pueda entender nuestro mensaje. La primera aproximación para conseguir esto es la que nos parece más evidente: sólo el receptor del mensaje sabrá cuales son las reglas o algoritmo para descifrar la información que yo envío. A esto se le conoce como &lt;i&gt;cifrado de algoritmo secreto&lt;/i&gt; y la verdad es que hoy en día está un poco caduco. Veamos por qué.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="fullpost"  style="font-size:95;"&gt;Probablemente, todo aquel que de pequeño haya formado parte de un club secreto sabrá a lo que me refiero. Lo más sencillo es establecer unas reglas para codificar la información que sólo conozcamos en el club. De ese modo será casi imposible, si las reglas son complicadas, que cualquier persona ajena pueda descifrar el mensaje. Pongamos un ejemplo, en cambio, de reglas sencillas.&lt;br /&gt;&lt;br /&gt;El cifrado más antiguo que se conoce se denomina &lt;b&gt;cifrado César&lt;/b&gt; y consiste en sumar a cada letra una cantidad para convertirla en otra del mismo abecedario. Si queremos codificar una 'a' y la clave es 5, sumamos 5 caracteres a la 'a' (b,c,d,e,&lt;b&gt;f&lt;/b&gt;) y la cambiamos por una 'f'. Cuando llegamos a las letras del final, por supuesto, reemplazamos por las primeras. Así, un mensaje 'abcdez' se codificaría como 'fghije'. Sencillo.&lt;br /&gt;&lt;br /&gt;Demasiado sencillo, claro. Pero aquí ha aparecido un concepto importante, que es el de &lt;b&gt;clave&lt;/b&gt;. Nuestra clave era 5 y, en principio, sin conocerla, no podíamos descifrar el mensaje... &lt;i&gt;aún conociendo las reglas de codificación&lt;/i&gt;. Bueno, en este caso sí, porque el algoritmo es muy sencillo: sabiendo que la regla consiste en sumar cierto número, para romper la clave sólo tendría que probar a ir sumando a cada carácter 1, luego 2, luego 3... hasta encontrar que la clave es 5 al leer un mensaje con sentido: a esto se le conoce como &lt;b&gt;ataque de fuerza bruta&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Pero a medida que el algoritmo se hace más complicado y las claves son largas y complejas, se puede asegurar con cierto rigor que un ataque de fuerza bruta encontrará la clave, en el peor de los casos, cuando la información enviada ya no tenga relevancia. Por eso hoy en día la tendencia es utilizar &lt;b&gt;algoritmos públicos&lt;/b&gt; -reglas- para codificar la información. Además, con Internet surgió un problema muy importante para los algoritmos secretos: en nuestro club infantil podemos acordar las reglas secretas en una reunión secreta en la casa del árbol (secreta). ¡Pero en Internet no existe esa posibilidad!: necesitas una &lt;i&gt;canal seguro&lt;/i&gt; para difundir las reglas secretas y es justamente eso lo que no tenemos&lt;a href="#fn1"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;El primer 'estándar &lt;i&gt;de facto&lt;/i&gt;' de los algoritmos públicos fue DES (&lt;i&gt;Data Encryption Standard&lt;/i&gt;). DES fue aprobado en 1976 y en 1998 se consiguió romper la clave mediante un ataque de fuerza bruta que duró 56 horas&lt;a href="#fn1"&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;. Si consideramos que la potencia de los computadores ha crecido exponencialmente todos esos años podemos otorgar más que un notable a este algoritmo. De todos modos para entonces DES ya había sido sustituido por una variante más compleja &lt;b&gt;Triple DES&lt;/b&gt; que en 2001 fue 'reemplazado' por otro algoritmo, &lt;b&gt;AES&lt;/b&gt; (&lt;i&gt;Advanced Encryption Standard&lt;/i&gt;). Se han especulado algunas debilidades de AES, pero por el momento no se conoce ningún ataque de fuerza bruta que pudiera dar resultado. Tanto es así que el Gobierno de los EE.UU., acostumbrado a los algoritmos secretos, anunció que podía emplear este método público para cifrar sus documentos TOP-SECRET. Así que es MUY, MUY DIFÍCIL romper una clave. Es MUCHO, MUCHO más sencillo robarla.&lt;br /&gt;&lt;br /&gt;Se llama &lt;b&gt;criptografía de clave simétrica&lt;/b&gt; a la que usa la misma clave para cifrar y para descifrar. Esto es lo más evidente y en lo que todos hemos estado pensando hasta ahora. Pero he aquí un problema: ¿cómo obtener una clave secreta?. Si emisor y receptor comparten ciudad, o país, la cosa es sencilla: quedan un día y, si tienen la seguridad de que la persona que tienen enfrente no es una impostora, acuerdan una clave segura. Pero si dos personas quieren intercambiar información a través de Internet y no pueden conocerse ¿cómo acuerdan la clave con seguridad?.&lt;br /&gt;&lt;br /&gt;Otro problema: si yo quiero comunicarme con Juan, gasto una clave secreta. Y con María otra clave  (no sea que Juan se entere) y con Antonio otra, Juan gasta otra distinta para comunicarse con Antonia... en fin, que para comunicarme con &lt;b&gt;n&lt;/b&gt; personas necesito &lt;b&gt;n&lt;/b&gt; claves distintas y esas son muchas: mejor las apunto en un POST-IT, ¿no?.&lt;br /&gt;&lt;br /&gt;Para solucionar estos problemas surgió la &lt;b&gt;criptografía de clave asimétrica&lt;/b&gt; que, básicamente, gasta una clave para cifrar y una pareja para descifrar. Y esto da mucho juego. Supongamos que yo en mi casa genero una pareja de claves y me quedo una para descifrar: esa es mi clave secreta. Pero la otra clave la publico en un servidor: &lt;i&gt;es mi clave pública&lt;/i&gt;. Entonces, si Juan quiere enviarme algo cifrado, coge mi clave pública, encripta la información con ella y me la envía. La gracia está en que sólo con mi clave privada se puede descifrar este mensaje y esa clave yo la tengo escondida: cualquier otro que lea el mensaje sólo encontrará un galimatías. Y lo mismo puede hacer María, Antonio...&lt;br /&gt;&lt;br /&gt;Pero, fatalidad, aquí el problema es otro: cuando me llega un mensaje cifrado con mi clave pública y firmado por Juan... ¿cómo sé yo que es Juan el que me lo envía?. No puedo: Juan debe &lt;b&gt;autenticarse&lt;/b&gt;. Pero... ¿y si lo hacemos al revés?: Juan publica una clave suya &lt;i&gt;para descifrar&lt;/i&gt;. Cifra el mensaje con mi clave pública para cifrar y cifra el resultado con su clave privada para cifrar. Entonces yo (y cualquiera) podré leer el mensaje cifrado por Juan sin más que coger la clave pública de Juan. El texto contendrá un galimatías: sólo yo puedo entenderlo gastando mi clave privada. Al mensaje cifrado con una clave privada para autenticarse se le llama &lt;b&gt;firma digital&lt;/b&gt;. La firma digital autentica, impide la alteración (añadiendo contenido al mensaje) y no es repudiable: Juan no puede alegar que ese mensaje no era suyo.&lt;br /&gt;&lt;br /&gt;¿Ya está?. No, nunca. Supongamos que Antonio quiere suplantar a Juan y cifra el mensaje: "Hola soy Juan" con una clave privada suya (la de Juan no la conoce). Y en el momento en que yo accedía a un servidor de claves para conocer la clave pública de Juan (y descifrar el mensaje), Antonio intercepta la comunicación y me envía SU clave pareja: entonces yo pensaré que el mensaje ha sido firmado por Juan. Es necesario que existan &lt;b&gt;Autoridades Certificadoras&lt;/b&gt; (AC). Estas sirven para garantizar que cierta clave pública corresponde a la de una entidad o persona. Para ello, tras comprobar la identidad del solicitante (y en los casos más serios se requiere la presencia física), la autoridad certificadora asocia en un documento la identidad de la persona con la clave pública y &lt;i&gt;firma digitalmente&lt;/i&gt; con su clave -la de la AC- esa asociación.&lt;br /&gt;&lt;br /&gt;Yo puedo exigir a Juan su firma digital obtenida de alguna AC de renombre. Por ejemplo, si quiero hacer la declaración de la renta por Internet se me exigirá una firma digital expedida por la administración. Cuando "Juan" contacte conmigo descifraré la firma digital con la clave pública de la AC (que se supone conocida) y obtendré la clave pública de Juan junto con sus datos personales. Y si alguien ha suplantado la clave pública de Juan de algún modo maligno la culpa es de la AC. Fácil, ¿no?.&lt;br /&gt;&lt;br /&gt;La verdad es que me he extendido mucho en este post y me he dejado muchas cosas en el tintero. Es un tema muy interesante que se presta al pensamiento &lt;i&gt;conspiranoico&lt;/i&gt;. Y es que cualquier comunicación mediante Internet, en algún punto de la misma, será insegura. Pero es lo que tiene la conspiranoia: nunca se puede acabar con ella: siempre puede dar un paso más e incluir a alguien más en la trama. Normal que algunas de estas teorías tengan tanto éxito, ¿no?&lt;br /&gt;&lt;br /&gt;&lt;div class="footnotes" id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; Eso no significa que los algoritmos secretos de codificación no se sigan utilizando. Los ejércitos (en especial el de EE.UU.) los emplean. Es lo que se llama &lt;i&gt;seguridad por ocultación&lt;/i&gt;.&lt;br /&gt;&lt;sup&gt;2&lt;/sup&gt; La empresa &lt;b&gt;RSA&lt;/b&gt; patrocinaba el concurso de rotura, otorgando un premio de 10000 dólares. El primer equipo que lo consiguió tardó 4 meses en encontrar la clave. En 1988 Distributed.Net ganó el segundo desafío en 41 días. Este equipo volvería a ganar en 1999 en un tiempo de 22 horas y 15 minutos, habiendo probado 245000 &lt;i&gt;millones de claves por segundo&lt;/i&gt;.&lt;/div&gt;&lt;br /&gt;&lt;div class="sources"&gt;Redes de Computadores (James F. Kurose, Keith W. Ross). Ed. Adison-Wesley&lt;br /&gt;Wikipedia: &lt;a href="http://es.wikipedia.org/wiki/Criptograf%C3%ADa"&gt;Criptografia&lt;/a&gt;, &lt;a href="http://es.wikipedia.org/wiki/Est%C3%A1ndar_de_Cifrado_de_Datos"&gt;DES&lt;/a&gt; (criptografía simétrica), &lt;a href="http://es.wikipedia.org/wiki/RSA"&gt;RSA&lt;/a&gt; (criptografía asimétrica).&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a class="reltext" onclick="return Mostra('rel')"&gt;Posts relacionados&lt;/a&gt;&lt;br /&gt;&lt;div class="related" id="rel"&gt;&lt;a href="http://civada.blogspot.com/2008/01/csi-ix-codificacin-de-datos.html"&gt;Codificación de datos&lt;/a&gt;&lt;br /&gt;&lt;a href="http://civada.blogspot.com/2008/02/csi-x-cuando-la-cosas-ocupan-menos.html"&gt;Compresión de datos&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150691805752037383-1905002930285688597?l=civada.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://civada.blogspot.com/feeds/1905002930285688597/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1150691805752037383&amp;postID=1905002930285688597" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/1905002930285688597" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/1905002930285688597" /><link rel="alternate" type="text/html" href="http://civada.blogspot.com/2008/03/csi-xii-criptografa-y-cifrado-de-datos.html" title="CSI XII: Criptografía y cifrado de datos" /><author><name>Delirium</name><uri>http://www.blogger.com/profile/08408043740617685786</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150691805752037383.post-1505081479469075925</id><published>2008-03-12T19:39:00.001+01:00</published><updated>2008-07-10T10:25:21.883+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Informática" /><title type="text">CSI XI: Códigos que corrigen errores</title><content type="html">&lt;span style="font-size: 95%;"&gt;En este blog hemos hablado bastante de codificación de datos. Lo hicimos para hablar de &lt;a href="http://civada.blogspot.com/2008/01/csi-ix-codificacin-de-datos.html"&gt;cómo se transmitía la información&lt;/a&gt; para que las características del medio de transmisión no afectasen demasiado a la señal. Y más tarde  os conté de qué manera se podía codificar la información &lt;a href="http://civada.blogspot.com/2008/02/csi-x-cuando-la-cosas-ocupan-menos.html"&gt;para que ocupase mucho menos espacio&lt;/a&gt;. En este último caso nos parecía estupendo que la misma información pudiese ocupar menos espacio del que ocupaba. Hoy en cambio codificaremos para que la información ocupe más.&lt;br /&gt;&lt;br /&gt;Siendo un poco ingenieriles: si ocupa más, tendrá mayor coste almacenar estos datos, así que, ¿qué ganamos al codificar la misma información con más bits?. Bien, pues en este caso en concreto, los bits añadidos nos servirán para saber si se produjo un error durante la transmisión de esta información. Y no sólo eso, sino que además nos permitirá recuperar la información original, esto es, reparar el fallo.&lt;br /&gt;&lt;br /&gt;Hoy hablaremos de &lt;b&gt;códigos detectores y correctores de errores&lt;/b&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="fullpost" style="font-size: 95%;"&gt;Para ello necesitamos cierta base. Este tema se presta a una modelización matemática mediante operaciones con matrices y cosas de esas, pero nosotros no llegaremos tan lejos. Nos bastará con entender un concepto muy sencillo: el de &lt;a href="http://en.wikipedia.org/wiki/Hamming_distance"&gt;distancia de Hamming&lt;/a&gt;&lt;a href="#fn1"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Empecemos: llamamos &lt;b&gt;código&lt;/b&gt; a una representación de datos que sigue ciertas reglas para su construcción. Por ejemplo, cuando hablé de la codificación Huffman os conté el proceso o reglas para obtener el código asignado a cada símbolo. Obteníamos para cada uno una palabra codificada. Ésta, por supuesto, satisfacía las reglas de la codificación.&lt;br /&gt;&lt;br /&gt;Aquí lo importante es ver que no todas la palabras posibles obedecen las reglas de la codificación. Dicho de otro modo: el conjunto de palabras codificadas es un subconjunto de todas las palabras posibles. Imaginemos que hemos diseñado nuestra codificación de modo que un error de un bit en la palabra provoque que la palabra resultante no pertenezca al conjunto de palabras codificadas. En ese caso, el receptor se dará cuenta de ello y asumirá que ha habido un error. Acabamos de detectar un fallo.&lt;br /&gt;&lt;br /&gt;Pongamos el ejemplo más típico: códigos de paridad par. Contamos el número de unos de cada palabra y añadimos un bit a la misma: un 1 si el total de unos es par y un 0 en caso contrario. El receptor realizará el mismo proceso: si ha habido un error de un bit en la transmisión, entonces el bit de paridad no coincidirá con el recibido. Por supuesto, el invento se nos va al traste si hay dos errores en la transmisión. Pero, ¿a que es maravilloso poder detectar, añadiendo un simple bit, todos las inversiones (fallos) posibles de un bit?.&lt;br /&gt;&lt;br /&gt;Vamos a poner una medida del número de fallos que puede detectar y corregir un código. Se define como &lt;b&gt;distancia de Hamming&lt;/b&gt; el número de bits en que se diferencian dos palabras. Tan sencilo como eso: la distancia de Hamming entre &lt;b&gt;100110&lt;/b&gt; y &lt;b&gt;101100&lt;/b&gt; es 2, porque cambian dos bits de una a la otra. &lt;i&gt;La distancia de Hamming de un código es la distancia de Hamming mínima entre dos palabras válidas del código distintas&lt;/i&gt;. El código de paridad par que hemos visto antes tiene una distancia de Hamming igual a 2. Porque la mínima distancia entre dos palabras distintas cualesquiera es 1 bit. Pero si hay un error que cambia un bit, entonces también el bit de paridad ha de ser distinto.&lt;br /&gt;&lt;br /&gt;&lt;a title="Ejemplo: distancia de Hamming"&gt;&lt;img style="float:right; margin:0 0 10px 10px;" src="http://img210.imageshack.us/img210/9444/transparentereduxua3.png" border="0" alt="" /&gt;&lt;/a&gt;Bien, pues aquí no se demostrará, pero el tema (temazo) es que para que un código detecte errores de &lt;b&gt;n&lt;/b&gt; bits, su distancia de Hamming debe ser mayor o igual a &lt;b&gt;n+1&lt;/b&gt;. Y para que un código corrija errores de &lt;b&gt;n&lt;/b&gt; bits, su distancia de Hamming debe ser mayor o igual a &lt;b&gt;2n+1&lt;/b&gt;. Y ya lo más: un código corrige hasta &lt;b&gt;n&lt;sub&gt;c&lt;/sub&gt;&lt;/b&gt; errores y detecta &lt;b&gt;n&lt;sub&gt;a&lt;/sub&gt;&lt;/b&gt; errores si cumple que su distancia de Hamming es mayor igual a &lt;b&gt;2n&lt;sub&gt;c&lt;/sub&gt;+n&lt;sub&gt;a&lt;/sub&gt;+1&lt;/b&gt;. &lt;br /&gt;&lt;br /&gt;En el dibujo de al lado podemos ver el más simple de los ejemplos. En el primer dibujo vemos un código de paridad par. De las 8 palabras posibles, sólo 4 son válidas. Cada arista representa una distancia de Hamming entre palabras igual a 1. En el primer caso, la distancia de Hamming del código es 2. Si transmitimos un 000 y se produce un error de un bit, entonces alcanzaremos una palabra no válida en el código (puntos negros). En cambio los errores de dos bits (011, 110, 101) serán tomados como palabras válidas.&lt;br /&gt;&lt;br /&gt;En el segundo caso las únicas palabras válidas del código son 000 y 111. La distancia de Hamming es entonces 3. Vemos como ahora se detectan errores de hasta dos bits (si damos dos saltos desde cualquier palabra válida llegamos a una no válida). Pero además, errores de 1 bit se 'corrigen' sustituyendo la palabra por la más cercana válida en el código. En cambio, errores de dos bits se corregirían incorrectamente.&lt;br /&gt;&lt;br /&gt;Evidentemente, la expresión de Hamming nos indica que, cuanto mayor sea el código que añadamos a la información (1 bit en el primer ejemplo, 2 en el segundo), mayor cantidad de errores podremos detectar y corregir. Pero claro, esa información añadida consume ancho de banda y espacio: supone más dinero. El ingeniero debe alcanzar un compromiso entre el coste de añadir esa información y los beneficios que genera. Como siempre.&lt;br /&gt;&lt;br /&gt;La generalización de estos códigos se emplea altamente, por ejemplo para detectar errores en memorias. Los &lt;b&gt;códigos SEC de Hamming&lt;/b&gt; (&lt;i&gt;Single Error Correcting&lt;/i&gt;) se utilizan para corregir un único error en la transmisión de datos. &lt;a href="http://en.wikipedia.org/wiki/Hamming_code#Hamming.287.2C4.29_code"&gt;El que Hamming propuso&lt;/a&gt; era capaz de corregir el fallo de 1 bit en 4 bits de datos, empleando códigos de 3 bits. Para corregir un fallo en 8 bits de datos empleando SEC, necesitamos 4 bits añadidos. Para 16 bits, 5 de código...&lt;br /&gt;&lt;br /&gt;Los códigos SEC de Hamming son muy sencillos de generar y muy eficientes. Por desgracia, tienen el problema de que cuando se producen más fallos de los tolerados, la corrección genera una palabra inválida y, en principio, no podemos saber si durante la transmisión se produce sólo uno o más fallos. Pero bueno... ¡ni siquiera Hamming era perfecto!&lt;br /&gt;&lt;br /&gt;&lt;div class="footnotes" id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; Pongo el enlace a la Wikipedia en inglés, porque en castellano está bastante pobre e incluso mal. Veré si lo puedo cambiar.&lt;/div&gt;&lt;br /&gt;&lt;div class="sources"&gt;Material de clase.&lt;br /&gt;Wikipedia: &lt;a href="http://en.wikipedia.org/wiki/Error_Correcting_Code#Hamming_distance_based_checks"&gt;Error detection and correction&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;a class="reltext" onclick="return Mostra('rel')"&gt;Posts relacionados&lt;/a&gt;&lt;br /&gt;&lt;div class="related" id="rel"&gt;&lt;a href="http://civada.blogspot.com/2008/02/csi-x-cuando-la-cosas-ocupan-menos.html"&gt;Compresión de datos: Huffman&lt;/a&gt;&lt;br /&gt;&lt;a href="http://civada.blogspot.com/2008/01/csi-ix-codificacin-de-datos.html"&gt;Codificación de datos: transmisión&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150691805752037383-1505081479469075925?l=civada.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://civada.blogspot.com/feeds/1505081479469075925/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1150691805752037383&amp;postID=1505081479469075925" title="2 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/1505081479469075925" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/1505081479469075925" /><link rel="alternate" type="text/html" href="http://civada.blogspot.com/2008/03/csi-xi-cdigos-que-corrigen-errores.html" title="CSI XI: Códigos que corrigen errores" /><author><name>Delirium</name><uri>http://www.blogger.com/profile/08408043740617685786</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150691805752037383.post-650587235965909075</id><published>2008-02-29T19:05:00.000+01:00</published><updated>2008-03-01T13:06:42.391+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Informática" /><title type="text">Cuando el informático la pifia</title><content type="html">&lt;span style="font-size: 95%;"&gt;A veces los informáticos hacen mal las cosas. Bueno, todo el mundo, pero los fallos informáticos tiene un &lt;i&gt;nosequé&lt;/i&gt; que los hace misteriosos. Un fallo informático siempre parece inexplicable, algo que no debería suceder. Pero ya sabemos que los fallos suceden. Un buen informático tiene que diseñar su aplicación de modo que esta sea lo más confiable posible. Esto incluye evitar que los fallos y errores se conviertan en averías: hace mucho tiempo ya hablamos de esto: se llama &lt;a href="http://en.wikipedia.org/wiki/Fault_tolerant"&gt;tolerancia a fallos&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Otras veces sencillamente, los errores son tan tontos que claman al cielo y merecen ser ocultados para salvar la vergüenza de sus responsable. O públicamente expuestos para su escarnio. Pues bien, en &lt;a href="http://catless.ncl.ac.uk/risks"&gt;Risk&lt;/a&gt; han optado por esto último. A modo de foro se exponen casos de lo que se conoce como "cagadas". Algunos tontos, otros graves, pero siempre evidentes. No todos son informáticos. No todos son &lt;i&gt;bugs&lt;/i&gt;. Pero todos son, al menos, curiosos.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="fullpost" style="font-size: 95%;"&gt;&lt;li&gt;La alarma de mi portátil funciona acorde con el tiempo local de Estados Unidos en vez de con el tiempo del Reino Unido (donde he viajado) sin que pueda cambiarlo. Esto sucede aunque cambie el tiempo local de mi portátil al del Reino Unido.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Una compañía de teléfonos de Taiwan ocultaba parte de los teléfonos en la correspondencia con los clientes. Por privacidad, en las misivas sólo se muestran los números pares del número de teléfono al que se da servicio  2*8*4*8*. Para mayor seguridad, también se ocultan los dígitos impares del número de contacto *5*5*7*0. Pero si resulta que éste coincide con el anterior, ¡entonces se está revelando todo el número!.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Un "0" se les cayó del precio de un PC vendido por Marubeni, una gran compañía de venta web.  Antes de que se dieran cuenta del error, alrededor de 1000 personas compraron 1500 unidades. En vez de 198000 yenes (unas 198000 pesetas) se vendieron a 19800 yenes. Tras percatarse del error, la compañía trató de oponer resistencia al cumplimiento del acuerdo. Sin embargo, finalmente decidieron ceder para mantener la fidelidad de sus compradores.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Después de que junto la cartera me robaran la tarjeta de crédito (&lt;i&gt;American Express&lt;/i&gt;), cancelé la misma y obtuve una nueva. Un mes después, habían sido cargados a mi cuenta dos gastos de &lt;i&gt;American-On-Line&lt;/i&gt; que yo no había realizado.&lt;br /&gt;&lt;br /&gt;Según AOL, dos cuentas se habían abierto a mi nombre y, cuando se intentó realizar algún gasto con ellas, AOL encontró que la tarjeta había sido cancelada. Sin embargo, ante estas situaciones, se consulta (automáticamente, claro) a American Express, cuya política es la de... ¡proporcionar el número de la nueva tarjeta!. Por cierto, las cuentas abiertas en AOL estaban a nombre de mi hija y de mi mujer. (&lt;i&gt;Esto no es un bug: esto es una cabronada de AmEx&lt;/i&gt;)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Adam Abrams no podía crear una cuenta en un servidor. Recibía un mensaje de notificación "&lt;i&gt;La razón por la que no puedes crear una cuenta es debido a que su dirección de correo ha sido marcada por nuestra tabla de palabras inadecuadas&lt;/i&gt;". Tras mucho investigar descubrió que no era "bra" (sujetador), el problema era "dam" (maldición).&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Envié una carta de referencia a la Fundación Hertz recomendando a un estudiante. La Fundación requiere una firma electrónica en la recomendación. La firma constaba de una página web con un formulario donde se podía leer algo así como: "Certifico que soy la persona de abajo:" y un cuadro donde escribir el nombre.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;En Nueva York murió una persona porque los servicios de emergencia no pudieron localizar su apartamento. El problema fue que vivía en en un edificio con una dirección de 5 dígitos, mientras que el sistema para enviar a los profesionales de los servicios de emergencia sólo admitía 4 dígitos.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;El &lt;a href="http://en.wikipedia.org/wiki/Ariane_5"&gt;Ariane 5&lt;/a&gt;, cohete estrella de la Agencia Espacial Europea voló por los aires el 4 de Junio de 1996 a los pocos segundos de su despegue. Al parecer una conversión de un  número de 64 bits en un entero de 16 resultó en un desbordamiento. Este entero controlaba la estabilidad del aparato, de modo que el cohete trató de rectificar su posición (correcta), inclinándose un poco. Cuando, error tras error, el cohete superó la inclinación de seguridad permitida, se autodestruyó. El error se había producido por una incorrecta adaptación del código (en Ada) que regía el Ariane 4.&lt;/li&gt;&lt;br /&gt;A veces, por más que se hagan bien las cosas, la fatalidad está asegurada.&lt;br /&gt;&lt;br /&gt;&lt;li&gt;En el desarrollo de un avión bombardero se diseñaron tres esquemas de prueba independientes para evitar cierto efecto causado por la vibración de la cola del aparato (&lt;i&gt;NOTA AL MARGEN: los aviones son tan seguros que llevan un retraso tecnológico de unos 15 años. Por seguridad, protocolos, planificadores, redes, tecnologías demasiado nuevas no se aplican a causa del temor a que fallen&lt;/i&gt;).&lt;br /&gt;&lt;br /&gt;1. Un túnel de viento fue construido expresamente para investigar el efecto de estas vibraciones. El túnel se probó sobre un modelo a escala del avión.&lt;br /&gt;2. Se hicieron test de resonancia sobre el primer prototipo, con los que se ajustaron ecuaciones aerodinámicas.&lt;br /&gt;3. Se hicieron test en vuelo a baja velocidad, cuyos resultados se extrapolaron para analizar las vibraciones a alta velocidad.&lt;br /&gt;&lt;br /&gt;Los tres tests condujeron a similares resultados y se concluyó que no había problema con el diseño de la cola para ninguna velocidad. Poco después, mientras el primer prototipo estaba realizando maniobras a alta velocidad y baja altura, la cola se rompió, estrellándose el avión y muriendo su tripulación. Acto seguido se inició una investigación, que concluyó con los siguientes resultados:&lt;br /&gt;&lt;br /&gt;1. La rigidez de una parte del túnel de viento construido no era la adecuada.&lt;br /&gt;2. Un término en las ecuaciones aerodinámicas era incorrecto.&lt;br /&gt;3. Los ingenieros se equivocaron al interpretar los resultados de los tests a baja velocidad.&lt;br /&gt;&lt;br /&gt;Y, debido a la mala fortuna, todos los resultados conducían a la misma errónea solución.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;Y, a veces, las cosas se hacen demasiado bien.&lt;br /&gt;&lt;br /&gt;&lt;li&gt;El sistema de teléfono de emergencia 911 de las mayores ciudades de Minnesota fue convertido a digital. De este modo se introducían menores interferencias en la lineas. La gente, que estaba acostumbrada a escuchar el ruido de la linea al descolgar el teléfono&lt;a href="#fn1"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; quedaba extrañada al no escuchar nada y pensaba que había un problema con su conexión.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="footnotes" id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; No en todos los lugares del mundo hay tonos&lt;/div&gt;&lt;br /&gt;&lt;div class="sources"&gt;&lt;a href="http://catless.ncl.ac.uk/risks"&gt;The RISK Digest&lt;/a&gt;. Forum On Risks To The Public In Computers And Related Systems&lt;/div&gt;&lt;br /&gt;&lt;a class="reltext" onclick="return Mostra('rel')"&gt;Posts relacionados&lt;/a&gt;&lt;br /&gt;&lt;div class="related" id="rel"&gt;&lt;a href="http://civada.blogspot.com/2007/06/el-trabajo-de-aitor-menta-i.html"&gt;Tolerancia a fallos: mi trabajo&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150691805752037383-650587235965909075?l=civada.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://civada.blogspot.com/feeds/650587235965909075/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1150691805752037383&amp;postID=650587235965909075" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/650587235965909075" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/650587235965909075" /><link rel="alternate" type="text/html" href="http://civada.blogspot.com/2008/02/cuando-el-informtico-la-pifia.html" title="Cuando el informático la pifia" /><author><name>Delirium</name><uri>http://www.blogger.com/profile/08408043740617685786</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150691805752037383.post-1232973124575939219</id><published>2008-02-16T17:25:00.003+01:00</published><updated>2008-07-10T10:24:45.377+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Informática" /><title type="text">CSI X: cuando la cosas ocupan menos</title><content type="html">&lt;span style="font-size: 95%;"&gt;Recuerdo perfectamente una de las primeras clases de informática, allá en primero. Bueno, no, eso sería casi un milagro habida cuenta que no recuerdo qué comí ayer... Pero sí que recuerdo una frase pronunciada por un profesor, a modo de jocosa obviedad. "Dicen que 'el saber no ocupa lugar'... ¡No pollas!".&lt;br /&gt;&lt;br /&gt;Y es que el saber, cualquier tipo de información, SÍ ocupa lugar. Y sea del tipo que sea, ese lugar tiene un coste o precio. El cerebro también tiene un coste, por más que algunos se empeñen en destrozarlo a base de etanol o mítines. Por ello siempre que podamos &lt;i&gt;comprimir&lt;/i&gt; los datos, información o saber (y el coste de la compresión no supere al de sus beneficios, claro está) nos interesará hacerlo. De este modo saldremos ganando espacio. Pero... ¿pueden ocupar las cosas menos lugar de lo que ocupan?. ¿Cómo se realiza este milagro?&lt;br /&gt;&lt;br /&gt;Pues eso, en Cosas que Sí se dan en Informática, hablaremos de compresión.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="fullpost" style="font-size: 95%;"&gt;Utilizaremos a modo de ejemplo las letras. Supongamos que queremos comprimir un fichero de texto que tan sólo contiene caracteres de nuestro alfabeto (unos 25 caracteres), por simplificar. Sabido es que en Informática los computadores sólo entienden de unos y ceros (bits). Bien, normalmente se emplean 8 bits para codificar caracteres (codificación &lt;a href="http://es.wikipedia.org/wiki/ASCII"&gt;ASCII&lt;/a&gt; extendida). Con 8 unos y ceros podemos codificar 256 (2&lt;sup&gt;8&lt;/sup&gt;) 'letras' distintas... pero si ya sabemos que nuestro fichero tiene tan sólo 25 letras distintas... ¿para qué queremos tantas?. Quitemos bits.&lt;br /&gt;&lt;br /&gt;Para codificar 25 caracteres distintos necesitamos al menos 5 bits, ya que 2&lt;sup&gt;5&lt;/sup&gt; es 32. Por tanto, un fichero con 10 caracteres ocuparía 50 bits. Pero imaginemos que, de estos 10 caracteres, 4 son '&lt;b&gt;a&lt;/b&gt;'s. ¿Ya que hay más '&lt;b&gt;a&lt;/b&gt;'s, no ganaríamos espacio si codificamos las '&lt;b&gt;a&lt;/b&gt;'s con unos pocos menos bits que el resto?.&lt;br /&gt;&lt;br /&gt;Esa es la idea base de la &lt;a href="http://es.wikipedia.org/wiki/Codificaci%C3%B3n_Huffman"&gt;codificación Huffman&lt;/a&gt;, desarrollada por el señor del mismo nombre en 1951. Aunque variantes de la misma codificación son más eficientes en determinadas circunstancias, Huffman encontró la forma óptima de mapear cualquier símbolo de una alfabeto con una secuencia de bits de longitud óptima. La idea es tan sencilla y elegante que bien merece la pena explicarla.&lt;br /&gt;&lt;br /&gt;&lt;a title="Construcción del árbol binario de Huffman"&gt;&lt;img style="float:right; margin:0 0 10px 10px;" src="http://img53.imageshack.us/img53/7097/huffmantq4.png" border="0" alt="" /&gt;&lt;/a&gt;Partimos de una alfabeto y una cadena de letras. Supongamos que nuestra cadena es '&lt;b&gt;aavnvavfja&lt;/b&gt;'. Conociendo la cadena, podemos asociar a cada símbolo de nuestro alfabeto una cuenta de apariciones. Esto se llama &lt;i&gt;histograma&lt;/i&gt;. Por tanto, tenemos que &lt;b&gt;a --&gt; 4, v --&gt; 3, n --&gt; 1, f --&gt; 1, j --&gt; 1&lt;/b&gt;. El resto de símbolos son ceros. Bien, pues ahora vamos a construir un &lt;i&gt;arbol binario&lt;/i&gt;. Árbol porque es un árbol al revés. Binario, porque cada rama se separa en 2 ramas. Cogeremos los dos símbolos con menor número de apariciones y los agruparemos, sumando sus apariciones: &lt;b&gt;'fj' --&gt; 2&lt;/b&gt;. Y volvemos a operar del mismo modo... y otra vez y otra... ¡hasta que la raíz del árbol agrupa todos los símbolos! (ver imagen).&lt;br /&gt;&lt;br /&gt;Y ya está. Porque si asignamos un bit a cada rama del árbol, '&lt;b&gt;0&lt;/b&gt;' para la izquierda '&lt;b&gt;1&lt;/b&gt;' para la derecha, podemos obtener el código para cada símbolo sin más que andarnos por las ramas encadenando estos bits hasta llegar al carácter que deseamos codificar. Codifiquemos, pues, nuestra cadena '&lt;b&gt;aavnvavfja&lt;/b&gt;'.&lt;br /&gt;&lt;b&gt;001011010010111011110&lt;/b&gt;&lt;br /&gt;Hemos utilizado 21 bits. De codificar cada símbolo con 8 bits habríamos gastado 80. 50 si sólo codificáramos con 5 (alfabeto de 25 letras). Y 30 si codificáramos cada símbolo de este alfabeto en particular &lt;b&gt;{a, v, n, f, j}&lt;/b&gt; con 3 bits.&lt;br /&gt;&lt;br /&gt;¿Está ya nuestra cadena comprimida?. Pues no. Porque además de comprimirla, queremos enviarla por correo, que le llegue a un amigo y que éste, sin tener ni idea de cual era la cadena original, poder descomprimirla y leerla. Para eso es necesario que nuestro amigo conozca, bien la tabla de códigos que hemos creado, bien el histograma de apariciones de la cadena original. Aunque el histograma puede ser muy grande si el alfabeto lo es, su tamaño será despreciable cuando consideremos cadenas de miles y miles de bits.&lt;br /&gt;Con el histograma nuestro amigo (o el descompresor de nuestro amigo) puede construir el mismo árbol que hemos creado y decodificar la cadena. Para ello sólo tiene que 'andarse por las ramas' con los símbolos que le han llegado.&lt;br /&gt;&lt;br /&gt;El primero es un &lt;b&gt;0&lt;/b&gt;. Se anda por la rama izquierda y llega a la '&lt;b&gt;a&lt;/b&gt;'. Ya tiene un símbolo. Otro &lt;b&gt;0&lt;/b&gt;: se anda por las ramas y consigue otra '&lt;b&gt;a&lt;/b&gt;'. Ahora un &lt;b&gt;1&lt;/b&gt;: rama derecha. &lt;b&gt;0&lt;/b&gt;, rama izquierda: ha encontrado una '&lt;b&gt;v&lt;/b&gt;'... y así hasta completar la cadena entera.&lt;br /&gt;&lt;br /&gt;Y ya está: una cadena que tendría 8 bits por símbolo de codificarse ASCII se comprimiría hasta 2.1 bits por símbolo (21 bits, 10 símbolos). Bueno, no está, porque este tema tiene mucha tela por cortar. ¿Sabéis que se puede calcular el mínimo de bits por símbolo necesarios para representar una cadena?. Lo hizo &lt;a href="http://es.wikipedia.org/wiki/Claude_Elwood_Shannon"&gt;Claude Shannon&lt;/a&gt;, padre de la teoría de a información, antes de que Huffman inventara este método. El mínimo número de bits con el que se puede codificar una cadena viene definido por la &lt;i&gt;entropía de primer orden&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;En nuestro caso, H = 2.046439. Así que nuestra codificación Huffman no está nada mal. Hay mejores codificadores que los de Huffman, ojo. Por ejemplo los &lt;a href="http://en.wikipedia.org/wiki/Arithmetic_coding"&gt;codificadores aritméticos&lt;/a&gt;. Sin embargo, Huffman se sigue gastando mucho... más que nada porque estos últimos (que tampoco son tan complicados de entender) están sujetos a patentes por parte de compañías poderosas. Lo de las patentes de &lt;i&gt;software&lt;/i&gt; también tiene tela. Porque en muchos casos es algo tan absurdo como patentar la forma de darle la vuelta a una tortilla. Y nadie que quiera dar la vuelta a una tortilla lo podrá hacer de ese modo (aunque se le ocurra a él sólo) sin arriesgarse a ser demandado.&lt;br /&gt;&lt;br /&gt;Con Huffman, la secuencia que obtenemos tras la descompresión es idéntica a la original. Se llama &lt;i&gt;compresión sin pérdidas&lt;/i&gt;. Pero en muchos casos podemos tolerar cierto grado de pérdidas, esto es, de calidad. Por ejemplo, el oído humano enmascara ciertas frecuencias por debajo de otras, de manera que al ir seguidas, no percibimos algunas de ellas. ¿Por qué almacenar esa información, pues?. Con esa idea funciona &lt;a href="http://en.wikipedia.org/wiki/MP3"&gt;MP3&lt;/a&gt;. O, en dos fotogramas seguidos el fondo de la imagen apenas cambia, ya que el protagonista sólo mueve el pie... ¿por qué almacenar dos veces el mismo fondo estático?... con esa (y otras muchas) idea funcionan los compresores de vídeo.&lt;br /&gt;&lt;br /&gt;A la compresión que se aprovecha de cómo percibimos nosotros la información se le llama &lt;i&gt;compresión basada en la fuente&lt;/i&gt;. Suele tener pérdidas, pero son aceptables, y obtenemos cotas altísimas de compresión. Pero de ellas ya hablaremos otro día...&lt;br /&gt;&lt;br /&gt;&lt;div class="sources"&gt;Apuntes de clase: ¡esto es básico!&lt;/div&gt;&lt;br /&gt;&lt;a class="reltext" onclick="return Mostra('rel')"&gt;Posts relacionados&lt;/a&gt;&lt;br /&gt;&lt;div class="related" id="rel"&gt;&lt;a href="http://civada.blogspot.com/2008/01/csi-ix-codificacin-de-datos.html"&gt;Codificación de datos&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150691805752037383-1232973124575939219?l=civada.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://civada.blogspot.com/feeds/1232973124575939219/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1150691805752037383&amp;postID=1232973124575939219" title="2 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/1232973124575939219" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/1232973124575939219" /><link rel="alternate" type="text/html" href="http://civada.blogspot.com/2008/02/csi-x-cuando-la-cosas-ocupan-menos.html" title="CSI X: cuando la cosas ocupan menos" /><author><name>Delirium</name><uri>http://www.blogger.com/profile/08408043740617685786</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150691805752037383.post-1418615933778350747</id><published>2008-01-12T12:30:00.001+01:00</published><updated>2008-07-10T10:24:23.579+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Informática" /><title type="text">CSI IX: Codificación de datos</title><content type="html">&lt;span style="font-size: 95%;"&gt;Una vez introdujimos &lt;a href="http://civada.blogspot.com/2007/12/csi-viii-transmisin-de-datos.html"&gt;qué era la codificación&lt;/a&gt;, en este post veremos algunas técnicas para codificar datos y señales digitales. Recordemos que una señal digital es una secuencia de niveles de tensión discretos: cada uno de ellos es un elemento de la señal. Las técnicas de codificación convierten cada bit de datos 0 o 1 en elementos de señal, buscando ciertas ventajas o características de la misma.&lt;br /&gt;&lt;br /&gt;¿Qué es lo que buscamos cuando queremos transmitir?. Pues, de normal, que la velocidad de transmisión sea elevada y que el número de errores pequeño. Pero también que el medio que utilicemos sea barato. Por desgracia, todo a la vez es imposible: canales con mayor ancho de banda aumentarán la velocidad de transmisión y, si están bien apantallados podrán transmitir a grandes distancias sin apenas ruido... ¡pero eso es muy caro!. ¿De qué manera puede ayudar la forma de la señal?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="fullpost" style="font-size: 95%;"&gt;&lt;a title="Click para agrandar" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://img53.imageshack.us/img53/3108/codificacionrd6.gif"&gt;&lt;img style="float:right; margin:0 0 10px 10px; cursor:hand;width: 200px; border:thin solid;" src="http://img53.imageshack.us/img53/3108/codificacionrd6.gif" border="0" alt="" /&gt;&lt;/a&gt;(Un poco más de vocabulario). Una señal es &lt;i&gt;unipolar&lt;/i&gt; si todos sus elementos tienen el mismo signo (tensión sólo positiva o solo negativa). &lt;i&gt;Polar&lt;/i&gt; cuando no. A veces transmitimos los datos sobre dos lineas, de forma que el elemento se transmite como &lt;i&gt;diferencia&lt;/i&gt; en la tensión de ambas. Así, un pico de tensión afectará al valor de las dos lineas, pero no a su resta: eso se llama &lt;b&gt;transmisión diferencial&lt;/b&gt;. ¡Pero pasemos ya a ver de qué maneras codificamos!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;No retorno cero - NRZ&lt;/b&gt;. Es la forma más sencilla de codificar: usamos un nivel de tensión para representar el 0 y otro distinto para el 1. Lo más normal es que se codifique de forma polar: un nivel negativo para el 1 y uno positivo para el 0 (&lt;b&gt;NRZ-Level&lt;/b&gt;). Se llama no retorno cero porque la señal se mantiene constante al transmitir dos datos seguidos idénticos. Es decir: no retorna al cero.&lt;br /&gt;Una variación de NRZ es &lt;b&gt;NRZInvertida&lt;/b&gt;, que es una &lt;i&gt;codificación diferencial&lt;/i&gt;: la señal se codifica atendiendo los elementos de señal adyacentes. NRZI, concretamente, codifica los 1s como cambios en el nivel de tensión de la señal. Los ceros se transmiten manteniendo la señal invariable. Una ventaja de NRZI respecto a NRZ es que, con NRZ, el receptor debe comparar la tensión recibida con un umbral para determinar cuáles son los 0s y 1s. Con NRZI, sólo debe monitorizar las transiciones, algo, en principio, más sencillo&lt;a href="#fn1"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;AMI-bipolar&lt;/b&gt;. AMI-bipolar es una técnica de codificación multinivel: utiliza más de dos niveles de tensión. Tres. AMIb codifica los 0 como ausencia de tensión y los 1 como niveles positivos y negativos, alternando en cada aparición de éste. Por eso AMI significa &lt;i&gt;Alternate Mark Inversion&lt;/i&gt;. Esta codificación tiene una ventaja importante sobre las dos primeras y es que elimina la componente continua &lt;b&gt;dc&lt;/b&gt; de la señal: la suma de los niveles de tensión da cero. Similar a AMI es &lt;b&gt;MLT-3&lt;/b&gt;, que transmite los 1s como ciclos de -1, 0, +1, 0, transmitiendo los 0s manteniendo el nivel.&lt;br /&gt;&lt;br /&gt;Por otro lado tiene un problema: la inserción de más niveles de tensión incrementan la necesidad de ancho de banda. El receptor tiene que distinguir entre tres niveles, y no dos, por tanto la señal tiene que tener "más espacio" si no queremos aumentar el número de confusiones. Es como si pongo un lápiz encima de una libreta y te pregunto si está a la derecha o a la izquierda. Es fácil responder sin equivocarte. Pero si te pregunto si está a la derecha, izquierda o en el medio, te lo estoy poniendo más difícil: cuanto más grande sea la libreta, más sencillo te resultará responder sin confundirte.&lt;br /&gt;&lt;br /&gt;Todas las técnicas anteriores tienen otro problema muy importante que ya apunté. Es imposible tener el mismo reloj para decidir cuánto dura cada elemento de señal. A la larga, uno de los dos se atrasará lo suficiente como para que emisor y receptor no estén de acuerdo en el número de bits enviados, sobretodo si el nivel no cambia. La solución consiste en codificar un flanco como medida de sincronización. Y eso es lo que hacen...&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Manchester&lt;/b&gt;. Lo que hace es, a mitad de un intervalo de bit, insertar una transición: un cambio de alto a bajo es un 0 y un 1 se codifica como flanco de subida&lt;a href="#fn1"&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;. &lt;b&gt;Manchester diferencial&lt;/b&gt; también hace siempre una transición a mitad del intervalo, pero no representa el dato: un 0 se transmite como una transición al inicio del bit y el 1 como ausencia de transición.&lt;br /&gt;&lt;br /&gt;Lo bueno de estas codificaciones es que proporcionan &lt;i&gt;sincronización&lt;/i&gt;: el transmisor está diciendo en la propia señal cuando cree él que toca la transición de mitad del intervalo. El receptor puede que piense que el primero está equivocado, pero si quiere entenderle, más le vale hacer caso de lo que dice el emisor y muestrear el valor del bit cuando toque. Además no tienen componente continua y proporciona cierta detección de errores si no se recibe la transición esperada. Por otro lado estamos gastando hasta 2 transiciones para enviar cada bit: es decir incrementamos la &lt;i&gt;velocidad de modulación&lt;/i&gt; (numero de transiciones por segundo). La señal, por tanto, requiere un ancho de banda mayor... o transmitirse a menor velocidad.&lt;br /&gt;&lt;br /&gt;Y eso es un problema si queremos redes de alta velocidad que sean baratas. Por eso se emplean más trucos ingeniosos. La tecnología es cara y los ingenieros baratos. Decíamos que AMI y NRZ daban problemas de sincronización con secuencias largas invariables. Pues lo que se hace es 'pasar' de los datos y transmitir lo que nos de la gana. Más o menos. &lt;b&gt;B8ZS&lt;/b&gt; y &lt;b&gt;HDB3&lt;/b&gt; están basados en AMI y funcionan con tablas: cada secuencia de 8 y 4 bits (respectivamente) se reemplaza (consultando una tabla y teniendo en cuenta la última secuencia) por otra secuencia que contiene &lt;b&gt;violaciones de código&lt;/b&gt;: códigos no permitidos por la codificación AMI, como dos niveles de tensión positiva seguidos. De esta manera introducimos transiciones que ayudan en la sincronización. Hay otros esquemas basados en tablas de sustitución, como &lt;b&gt;4B5B&lt;/b&gt; o &lt;b&gt;8B10B&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;Hay maneras más sencillas de violar código. En NRZI podemos acordar que no permitiremos más de cinco ceros seguidos, por ejemplo. Y si encontramos una cadena con 5 ceros, cogemos y le endosamos un 1. El receptor, siempre que encuentre 5 ceros seguidos, sabe que el 1 siguiente lo he puesto yo, y entonces lo quita. Son lo que se llama &lt;b&gt;bits de relleno&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;Y con esto ya he puesto bastantes ejemplos. Si piensas que esto no vale para nada y tiene puesto un cable Ethernet en tu red local, te equivocas. Porque Ethernet a 100MB-TX utiliza un esquema 4B5B: sustituye secuencias de 4 bits por secuencias de 5, impidiendo cadenas de 1s o o 0s demasiado largas y luego lo codifica con MLT-3. Y si gastas USB, has de saber que utiliza transmisión diferencial a 1'5V y codifica utilizando NRZI con bits de relleno.&lt;br /&gt;&lt;br /&gt;Bueno no, no has de saberlo. ¡Para eso están otros!.&lt;br /&gt;&lt;br /&gt;&lt;div class="footnotes" id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; Hay otra ventaja y es que, gastando transmisión diferencial, las lineas pueden intercambiarse por error sin alterar el significado de la señal.&lt;br /&gt;&lt;sup&gt;2&lt;/sup&gt; En realidad, hay discusión acerca si debería ser al revés, tal y como sostiene &lt;a href="http://en.wikipedia.org/wiki/Andrew_S._Tanenbaum"&gt;Tanenbaum&lt;/a&gt;. Yo he seguido el criterio de &lt;a href="http://en.wikipedia.org/wiki/William_Stallings"&gt;Stallings&lt;/a&gt;, adoptado en Ethernet.&lt;/div&gt;&lt;br /&gt;&lt;div class="sources"&gt;Apuntes de clase (¡tienen ya unos años!)&lt;br /&gt;Wiquipedia (inglés): &lt;a href="http://en.wikipedia.org/wiki/Non-return-to-zero"&gt;NRZ&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Bipolar_encoding#Alternate_Mark_Inversion"&gt;AMI&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/MLT-3_encoding"&gt;MLT-3&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Manchester_code"&gt;Manchester&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/4B5B"&gt;4B5B&lt;/a&gt;.&lt;br /&gt;&lt;a href="http://www.beyondlogic.org/usbnutshell/usb2.htm"&gt;USB in a Nutshell&lt;/a&gt;. Hardware&lt;/div&gt;&lt;br /&gt;&lt;a class="reltext" onclick="return Mostra('rel')"&gt;Posts relacionados&lt;/a&gt;&lt;br /&gt;&lt;div class="related" id="rel"&gt;&lt;a href="http://civada.blogspot.com/2007/12/csi-viii-transmisin-de-datos.html"&gt;Transmisión de datos&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150691805752037383-1418615933778350747?l=civada.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://civada.blogspot.com/feeds/1418615933778350747/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1150691805752037383&amp;postID=1418615933778350747" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/1418615933778350747" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/1418615933778350747" /><link rel="alternate" type="text/html" href="http://civada.blogspot.com/2008/01/csi-ix-codificacin-de-datos.html" title="CSI IX: Codificación de datos" /><author><name>Delirium</name><uri>http://www.blogger.com/profile/08408043740617685786</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150691805752037383.post-6897089308150480994</id><published>2007-12-24T12:50:00.000+01:00</published><updated>2007-12-25T12:26:06.138+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Informática" /><title type="text">CSI VIII: Transmisión de datos</title><content type="html">&lt;span style="font-size: 95%;"&gt;Bien, con este post regresamos al fascinante mundo de la Cosas que Sí se dan en Informática. En &lt;a href="http://civada.blogspot.com/2007/09/csi-cmo-funciona-internet.html"&gt;capítulos anteriores&lt;/a&gt; vimos cómo podíamos transmitir datos sobre redes distintas (Internet). Y entonces comenté que los datos (0s y 1s) no son siempre lo que parecen, sino que se codifican de cierta forma buscando algunas propiedades.&lt;br /&gt;&lt;br /&gt;En el post de hoy vamos a meternos un poco más en harina para dejar claro conceptos que a menudo se confunden. Con esa base teórica explicaremos algunas técnicas de codificación. Empezamos con términos. &lt;b&gt;Dato&lt;/b&gt; es &lt;i&gt;cualquier entidad capaz de transmitir información&lt;/i&gt;. &lt;b&gt;Señal&lt;/b&gt; es la &lt;i&gt;representación eléctrica o electromagnética de los datos&lt;/i&gt;. La &lt;b&gt;señalización&lt;/b&gt; es el hecho de la propagación física de las señales a través del medio. Y lo que queremos es comunicar datos mediante su propagación y procesamiento de señales.&lt;br /&gt;Bienvenidos al universo de la &lt;b&gt;transmisión de datos&lt;/b&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="fullpost" style="font-size: 95%;"&gt;Con ejemplos se ve más claro. La voz es el típico caso de dato analógico: toma valores continuos en el tiempo. Los datos digitales toman en cambio valores discretos (prefijados) en el tiempo. Un ejemplo claro son las cadenas de caracteres. Las señales analógicas son ondas electromagnéticas que varían continuamente y que pueden propagarse por &lt;b&gt;medios guiados&lt;/b&gt; (un cable de teléfono) o no (el aire). Las señales digitales son secuencias de pulsos de tensión, transmitidos por un medio conductor, como el cable USB.&lt;br /&gt;&lt;br /&gt;Entonces ¿los datos analógicos se transmiten mediante señales analógicas y viceversa?. Sí, pero no sólo. En un teléfono típico, la voz (que se mueven en una frecuencia entre 100Hz y 7kHz) se transmite mediante una señal analógica entre 300Hz y 3400Hz. Esto es más que suficiente, pues la mayor parte de la energía de la voz se concentra entre los 700Hz y menos de 2kHz. En el otro extremo el teléfono realiza el proceso inverso y la voz resultante es muy parecida... pero no igual.&lt;br /&gt;&lt;br /&gt;¿Qué pasa cuando queremos enviar un fichero (datos digitales) a través de una linea de teléfono (transmisión analógica)?. Que necesitamos un &lt;b&gt;modem&lt;/b&gt;: un aparato que &lt;i&gt;modula&lt;/i&gt; los datos en una señal de cierta frecuencia &lt;i&gt;portadora&lt;/i&gt;. ¿Y cuando necesitamos ciertos &lt;b&gt;codecs&lt;/b&gt; para ver una peli en el ordenador? Pues que necesitamos algo que transforme señales digitales en datos analógicos y viceversa. Si no, no va.&lt;br /&gt;&lt;br /&gt;Y falta lo más fácil: representar datos digitales mediante señales digitales. Eso es muy sencillo. Si tenemos un dato, por ejemplo un uno, lo representamos con un nivel alto de tensión. Y si tenemos un cero, con un nivel bajo o ausencia de tensión. Y listo. Bueno, sí, pero no se hace de este modo, sobretodo cuando queremos transmitir grandes cantidades de datos y a largas distancias. Es entonces cuando &lt;b&gt;codificamos&lt;/b&gt; la señal. &lt;br /&gt;&lt;br /&gt;En general, desde ya hace unos años, la transmisión digital se ha impuesto a la analógica. La razón primordial es que es más barato y sencillo lidiar con señales digitales. Las nuevas tecnologías (como fibra óptica) se abaratan y resulta factible tender dorsales a lo largo del océano para comunicar continentes. Se trabaja más fácilmente con señales digitales en la eliminación de ruido, mientras que es necesario aplicar filtros de frecuencias en amplificadores analógicos para evitar la transmisión de señales molestas. Asimismo, es más seguro aplicar técnicas de cifrado sobre datos originalmente digitales que analógicos.&lt;br /&gt;&lt;br /&gt;Pero la transmisión digital tiene sus inconvenientes. Especialmente molesta es la &lt;b&gt;atenuación&lt;/b&gt; de la señal. Ésta, a largas distancias, se deforma. La calidad del medio transmisor es un factor clave en este caso. Por otro lado existe lo que llamamos &lt;b&gt;ruido&lt;/b&gt;, que no es más que la intromisión de señales no deseadas en la nuestra. En ocasiones un pico de intensidad de corriente puede provocar un salto en la señal. En transmisión de voz podríamos oírlo como un chasquido sin la menor importancia. En la señal digital puede provocar que un bit a cero en el origen se vea como un uno en el destino, provocando un error en el mensaje.&lt;br /&gt;&lt;br /&gt;¿En qué cosas puede ayudar la codificación empleada?. Pues nos puede ayudar a bajar la frecuencia de señal. Las señales con ausencia de componentes de alta frecuencia se pueden transmitir por canales con menor ancho de banda&lt;a href="#fn1"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;. Además, es deseable que la señal no tenga componente de continua, esto es, que que la suma de sus tensiones (señales) se acerque a cero, ya que así se reducen las interferencias.&lt;br /&gt;&lt;br /&gt;Pensemos en otro problema menos "físico". ¿Cómo sabemos lo que dura un elemento de la señal (por ejemplo un 1)?. Supongamos que somos el receptor y recibimos, durante un milisegundo, un nivel alto de tensión. ¿Cuántos unos hay ahí?. Vale que podemos ponernos de acuerdo con el receptor para decidir cuando dura... ¡pero el problema es que jamás tendremos el mismo reloj!. Imaginemos que cada uno dura 100ns. Si su reloj se adelanta medio ns respecto al mío, al cabo del microsegundo yo me creeré que he recibido 10 unos... ¡pero él me habrá enviado 15!. Bueno, pues la codificación también puede ayudar en este problema de &lt;i&gt;sincronización&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;La codificación también puede ayudar a detectar errores. ¿Qué cómo?. Pues imaginemos que, al codificar, añadamos un bit 0 si el número de 1s transmitidos es par y 1 si es impar. En ese caso el receptor cuenta los unos y, si la paridad no concuerda, sabe que ha existido un fallo&lt;a href="#fn1"&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;. Claro, que si ha habido un número par de fallos, la cosa ya no funciona. Pero algo tan simple detecta gran número de fallos a bajo nivel, antes de que el software, más lento, se dé cuenta.&lt;br /&gt;&lt;br /&gt;La codificación también sirve para minimizar el ruido. Ya veremos cómo. Y por último... hasta ahora hemos estado pensando en codificar UN bit de datos en UN elemento de tensión, pero, ¿y si decido tener no dos sino cuatro niveles de tensión?. Entonces podré codificar DOS bits en UN elemento. Con esta operación tan sencilla acabo de duplicar la capacidad de mi canal... y le he puesto mucho más difícil al receptor enterarse de lo que digo.&lt;br /&gt;&lt;br /&gt;Y ya paro. Y en el siguiente post veremos algunas de estas técnicas maravillosas.&lt;br /&gt;&lt;br /&gt;&lt;div class="footnotes" id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; No hay que confundir ancho de banda con la velocidad de transmisión, ojo, aunque estén relacionados (lo dijo &lt;a href="http://en.wikipedia.org/wiki/Nyquist_rate"&gt;Nyquist&lt;/a&gt;). Ancho de banda de un canal hace referencia a las frecuencias que "caben" en él. La velocidad de transmisión son los bits por segundo que se transmiten.&lt;br /&gt;&lt;sup&gt;2&lt;/sup&gt; Ver: &lt;a href="http://es.wikipedia.org/wiki/Bit_de_paridad"&gt;bit de paridad&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="sources"&gt;Mis apuntes de Redes. Tomados del famoso &lt;a href="http://prenhall.com/stallings/"&gt;Stallings&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;a class="reltext" onclick="return Mostra('rel')"&gt;Posts relacionados&lt;/a&gt;&lt;br /&gt;&lt;div class="related" id="rel"&gt;&lt;a href="http://civada.blogspot.com/2007/10/csi-vii-cmo-funciona-internet-ii.html"&gt;Cómo funciona Internet (II)&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150691805752037383-6897089308150480994?l=civada.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://civada.blogspot.com/feeds/6897089308150480994/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1150691805752037383&amp;postID=6897089308150480994" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/6897089308150480994" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/6897089308150480994" /><link rel="alternate" type="text/html" href="http://civada.blogspot.com/2007/12/csi-viii-transmisin-de-datos.html" title="CSI VIII: Transmisión de datos" /><author><name>Delirium</name><uri>http://www.blogger.com/profile/08408043740617685786</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150691805752037383.post-2879547795578886758</id><published>2007-11-15T19:20:00.000+01:00</published><updated>2007-11-15T19:27:39.233+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Informática" /><title type="text">Identificar personas: tarea de informático</title><content type="html">&lt;span style="font-size: 95%;"&gt;Los informáticos... ¿de qué trabajan?. O mejor aún, ¿para qué sirve un informático?. Más concretamente: ¿y un informático que ha estudiado Inteligencia Artificial?. ¿&lt;i&gt;Cyborgs&lt;/i&gt; en España?. No me hagan reír, hombre. El caso es que el amigo &lt;a href="http://joseluispinar.blogspot.com" title="El rincón del Pinar"&gt;Pinar&lt;/a&gt;, trabajar aún no, pero acaba de terminar la carrera (especialidad IA) con un interesante proyecto que demuestra cómo la informática se puede aplicar a muchos problemas sencillos en otros campos. Aquí, con su permiso, les cuento de qué va.&lt;br /&gt;&lt;br /&gt;Los artículos son la base de la producción científica. Escritos normalmente por más de un investigador&lt;a href="#fn1"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; suelen publicarse en revistas especializadas y congresos. En revistas importantes incluso se paga por publicar. A cambio, los autores ganan en prestigio o méritos académicos (consiguen un doctorado, por ejemplo). Los artículos se almacenan en bases de datos especializadas -algunas de pago- a través de las cuales se pueden consultar total o parcialmente. Podemos consultar el nombre de un autor, por ejemplo, pero... ¿¿¿quién es, en realidad, ese nombre???&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="fullpost" style="font-size: 95%;"&gt;Veamos otro problema parecido. Supongamos que tenemos dos artículos. Uno de ellos asociado a la &lt;i&gt;Polytech Univ Valencia, Valencia&lt;/i&gt; y otro a &lt;i&gt;Valencia Univ Technol, Valencia 46022&lt;/i&gt;. Vale es evidente que corresponden a la misma institución, evidente para un humano. Tenemos que tener a una persona encargada de revisar y comprobar que las distintas versiones de una institución se corresponden (o no) a una única institución. Este es un (aburrido) trabajo que se realiza de forma manual.&lt;br /&gt;&lt;br /&gt;Pero más pesado y difícil es identificar el/los autores de un artículo. Porque los nombres no se presentan de forma estándar. Porque hay países (en general de habla hispana) en los que muchas personas tienen dos nombres y dos apellidos. Porque los nombres se transcriben a menudo con errores. Así que, por ejemplo, si tenemos dos artículos, uno firmado por &lt;i&gt;J. Morno Pérez&lt;/i&gt; y otro firmado por &lt;i&gt;Juan Moreno P.&lt;/i&gt; puede pasar:&lt;br /&gt;&lt;br /&gt;Que ambos artículos sean escritos por el mismo investigador, llamado &lt;i&gt;Juan Moreno Pérez&lt;/i&gt;. O que el primero haya sido escrito por el tal &lt;i&gt;José Moreno Pérez&lt;/i&gt; y el segundo por otro señor, Juan Moreno Piqueras. O más difícil: pongamos que existe un tercer investigador llamado &lt;i&gt;Javier Morno Pérez&lt;/i&gt;. En ese caso, ¿a quién corresponde el primer artículo, a José o a Javier?. &lt;br /&gt;&lt;br /&gt;Los problemas, en general, son dos: la &lt;b&gt;homonimia&lt;/b&gt; (personas con nombres parecidos) y la &lt;b&gt;polisemia&lt;/b&gt; (variantes de un mismo nombre). Y es que el lenguaje natural es ambiguo. Si a eso le sumamos errores de transcripción, el problema de la &lt;i&gt;desambigüación&lt;/i&gt; puede ser muy complejo. Estos dos problemas también se dan en el tratamiento del lenguaje natural y los nombres provienen de ahí.&lt;br /&gt;&lt;br /&gt;Actualmente, aunque éste es un problema conocido, no existen soluciones universales. Podemos poner a un experto que se encargue, atendiendo al resto de información de la que dispone, de relacionar correctamente autores e investigadores para su clasificación. El problema es que cuando la cantidad de artículos es muy grande esta tarea conlleva una perdida de tiempo demasiado grande. El proyecto de Pinar tratará de automatizar un sistema para ofrecer una clasificación y (algo muy importante) una medida de la &lt;i&gt;confianza&lt;/i&gt; que podemos tener en ella. De este modo al menos facilitaremos la tarea del experto.&lt;br /&gt;&lt;br /&gt;El trabajo de Pinar parte de que ya tenemos cierta información acerca de investigadores, independiente de la de los artículos. En concreto disponemos de información institucional acerca de investigadores que solicitaron la realización de un proyecto y en qué lugar (institución). Atendiendo a esos datos, el trabajo consistiría en clasificar la producción científica -artículos- referida a ese área de estudio durante un periodo de unos 15 años y &lt;b&gt;determinar qué autores de estos artículos se corresponden con los investigadores que aparecen en la base de datos que tenemos&lt;/b&gt;. Concretamente se recopilaron más de 20.000 artículos, escritos por más de 75.000 autores.&lt;br /&gt;&lt;br /&gt;A obtener nueva información a partir de relaciones no explícitas entre diversas bases de datos se le llama &lt;b&gt;minería de datos&lt;/b&gt; y supone añadir una capa de &lt;i&gt;inteligencia&lt;/i&gt; a partir de simples datos.&lt;br /&gt;&lt;br /&gt;La idea básica es que si un artículo ha sido escrito por un investigador, entonces la información que tenemos del autor y artículo &lt;i&gt;se parece más&lt;/i&gt; a la información que tenemos sobre ese investigador que no a la otro. Ahora hay que pasar esta idea a términos matemáticos para poder aplicar un algoritmo. Esa es la parte difícil que en este blog no aparecerá.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;A grosso modo&lt;/i&gt;: se compara la similitud entre los nombres de los investigadores y los nombres de los autores del artículo. Para ello existen algoritmos muy conocidos para comparar cadenas, que nos dan una &lt;b&gt;distancia&lt;/b&gt; o medida de lo que se parecen (ej: &lt;a href="http://es.wikipedia.org/wiki/Distancia_de_Levenshtein"&gt;distancia de Levenshtein&lt;/a&gt;). Lo siguiente que podemos comparar es el título del artículo con el título del proyecto que figura en nuestra base de datos original. También podemos medir cuánto se parece el lugar de trabajo del investigador con el lugar de trabajo de los autores del artículo. Y mucho más: distancia en tiempo de la fecha de aprobación del proyecto con la fecha de publicación del artículo, o similitud con artículos ya asignados: si ya sabemos que tal investigador escribió un artículo, es probable que sea el autor de un segundo artículo parecido.&lt;br /&gt;&lt;br /&gt;Una vez decidimos qué parecidos son importantes (y cuánto, asignándoles un coeficiente), sólo nos queda seleccionar un algoritmo de clasificación: estos sirven para clasificar un conjunto de datos en clases. Es como poner una etiqueta a cada dato. En nuestro caso, pondremos una etiqueta a cada artículo con el nombre del investigador. Algunos algoritmos requieren que un subconjunto de datos estén ya correctamente clasificados (se llaman &lt;b&gt;aprendizaje supervisado&lt;/b&gt;) y otros no. Nos quedaremos con el algoritmo que mejor clasifique. El tiempo que tarde en hacerlo nos da relativamente igual.&lt;br /&gt;&lt;br /&gt;Pues eso ha estado estudiando Pinar. Y lo debe haber hecho bien, porque está escribiendo algún artículo sobre el tema. Esperemos que su nombre se publique sin errores y todos sepamos que lo ha escrito él mismo.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Pinar dice: "seguro que ponen 'Piñar', como en mi título de inglés".&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="footnotes" id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; En realidad lo escribe uno sólo y todos los doctores por encima del mismo ponen su firma. ;-)&lt;/div&gt;&lt;br /&gt;&lt;div class="sources"&gt;Artículo revisado y con el visto bueno del Rincón de Pinar!&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150691805752037383-2879547795578886758?l=civada.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://civada.blogspot.com/feeds/2879547795578886758/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1150691805752037383&amp;postID=2879547795578886758" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/2879547795578886758" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/2879547795578886758" /><link rel="alternate" type="text/html" href="http://civada.blogspot.com/2007/11/identificar-personas-tarea-de.html" title="Identificar personas: tarea de informático" /><author><name>Delirium</name><uri>http://www.blogger.com/profile/08408043740617685786</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150691805752037383.post-2108167592503849433</id><published>2007-10-12T08:49:00.001+02:00</published><updated>2008-12-09T07:29:35.885+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Informática" /><title type="text">CSI VII: Cómo funciona Internet (II)</title><content type="html">&lt;span style="font-size: 95%;"&gt;No tenía pensado escribir una segunda parte de este tema. Me parecía que ya había quedado más o menos claro el funcionamiento de Internet en el &lt;a href="http://civada.blogspot.com/2007/09/csi-cmo-funciona-internet.html"&gt;anterior post&lt;/a&gt;. Craso error. No queda nada claro, excepto para mí, que ya lo entiendo. A alguien que lo está leyendo le parecerá que ni siquiera tiene nada que ver con Internet. Por eso en este segundo post me propongo explicar qué es lo que quería decir con un sencillo ejemplo, tomado de la vida misma. Es decir, nada de metáforas.&lt;br /&gt;&lt;br /&gt;En el anterior post lo que quería explicar es que, para comunicarnos entre distintas redes (como Internet) necesitamos información de nuestra red. En especial dónde hay un dispositivo encaminador que conozca otras redes (&lt;i&gt;router&lt;/i&gt;), información acerca de la dirección destino (&lt;i&gt;dirección IP&lt;/i&gt;), unas reglas sobre cómo se producirá la comunicación (que llamamos &lt;i&gt;transporte&lt;/i&gt;) y un lenguaje común a ambos para entender qué deseamos del otro: a esto se le llama &lt;i&gt;protocolo de aplicación&lt;/i&gt;. Estructuramos esta información en capas, de manera que, si cambiamos una de ellas, no tenemos porqué cambiar las que están por debajo o por encima. Veamos cómo queda.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="fullpost" style="font-size: 95%;"&gt;Uno de los protocolos de aplicación más útiles, usados y conocidos es &lt;a href="http://es.wikipedia.org/wiki/DNS"&gt;DNS&lt;/a&gt; (&lt;i&gt;Domain Name System&lt;/i&gt;). Aunque DNS puede servir para más cosas, su función principal en Internet es proporcionar las direcciones IP de los nombres de equipo. Por ejemplo, tomemos el nombre de equipo &lt;i&gt;google.es&lt;/i&gt; al que accedemos desde España. Pero ya sabemos que en Internet los equipos se identifican con números, direcciones IP. La traducción de este nombre, sencillo de recordar, a dirección IP la realizan los servidores DNS. En este caso, la dirección IP es 72.14.207.191 (aunque lo más seguro es que haya más de una IP para este nombre).&lt;br /&gt;&lt;br /&gt;DNS da para muchos posts. Diremos sólo que el servicio funciona de forma jerárquica. Probablemente tendremos un servidor DNS cercano y a éste irán nuestras preguntas del tipo "¿qué dirección IP tiene www.talmaquina.com?". Si nuestro servidor cercano lo sabe, perfecto. Pero si no, él tiene un servidor DNS &lt;i&gt;por encima&lt;/i&gt; y le pregunta a éste. "¿Oye, tú sabes qué dirección IP tiene www.talmaquina.com?". Si ese servidor no lo sabe, contestará algo así como: "No, ni idea, pero pregunta a 'Otro servidor' que sabe más'". ¡Lo típico cuando preguntamos direcciones!. Y así va preguntando hacia arriba. Y arriba de todo están los &lt;a href="http://es.wikipedia.org/wiki/Servidor_Raiz"&gt;super-servidores DNS de primer nivel&lt;/a&gt;, de los cuales hay 13 distribuidos geográficamente de forma equitativa: 7 en EE.UU. y el resto desperdigados.&lt;br /&gt;&lt;br /&gt;Volvamos a lo nuestro, supongamos que yo tecleo el nombre de una dirección web en mi navegador: www.dimequenoexiste.com. ¿Qué es lo que pasará? Que mi navegador tratará de averiguar cuál es la dirección de la máquina con ese dominio para contactar con ella y pedirle una página &lt;i&gt;html&lt;/i&gt;, típicamente. Para eso, efectuará una petición DNS.&lt;br /&gt;&lt;br /&gt;La petición que quiero mandar al servidor DNS es: "¿qué dirección IP tiene www.dimequenoexiste.com?". Esa pregunta la codifico según el &lt;b&gt;protocolo DNS&lt;/b&gt;. DNS, por otro lado, funciona sobre el protocolo de &lt;b&gt;transporte UDP&lt;/b&gt;. Recordemos que los protocolos de transporte servían para añadir cierta coherencia al lío de la fragmentación de paquetes que se producía al gastar IP, y al hecho de que podían llegar desordenados o perderse. &lt;a href="http://es.wikipedia.org/wiki/User_Datagram_Protocol"&gt;UDP&lt;/a&gt; no ofrece tanta garantía como TCP, es más sencillo: apenas añade información del número de puerto para identificar el servicio (ahora DNS). &lt;i&gt;Metemos la información DNS dentro del paquete UDP. Toda esa información la meteremos en un &lt;b&gt;paquete IP&lt;/b&gt;&lt;/i&gt;, para que viaje por Internet. Como yo me conecto a Internet gracias a una red Ethernet, &lt;i&gt;tendré que meter el paquete IP dentro de una &lt;b&gt;trama Ethernet&lt;/b&gt;&lt;/i&gt;. El controlador de Ethernet (que está en la tarjeta de red) se encarga de &lt;b&gt;codificar&lt;/b&gt; esos unos y ceros de la mejor manera para transmitirlos.&lt;br /&gt;&lt;br /&gt;&lt;a title="Click para agrandar" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_dk7-LG3RBOQ/Rw9Ty7QRuxI/AAAAAAAAAOc/zoklnC0273o/s1600-h/EsquemaTCP-IP2.gif"&gt;&lt;img style="float:right; margin:0 0 10px 10px; cursor:hand;" src="http://2.bp.blogspot.com/_dk7-LG3RBOQ/Rw9Ty7QRuxI/AAAAAAAAAOc/zoklnC0273o/s320/EsquemaTCP-IP2.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5120403435708070674" /&gt;&lt;/a&gt;En total, 5. 5 niveles, que fueron los explicados en el anterior post. En la imagen vemos como se forma cada paquete y se mete en el del nivel inferior. Al navegador que gastamos, por ejemplo, la información acerca de las direcciones Ethernet utilizadas le importa un pimiento. De ahí que podamos hacer navegadores sin preocuparnos de esta cuestión.&lt;br /&gt;&lt;br /&gt;&lt;a title="Click para agrandar" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_dk7-LG3RBOQ/Rw87eLQRuuI/AAAAAAAAAOE/Oey5PNRlPwg/s1600-h/CapturaDatos.JPG"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:hand; " src="http://3.bp.blogspot.com/_dk7-LG3RBOQ/Rw87eLQRuuI/AAAAAAAAAOE/Oey5PNRlPwg/s200/CapturaDatos.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5120376690946718434" /&gt;&lt;/a&gt;Una vez hecha la pregunta, el servidor nos contestará gastando el mismo protocolo DNS. En la segunda imagen podemos ver la respuesta&lt;a href="#fn1"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;. Podemos identificar los distintos paquetes de información de la respuesta. Arriba Ethernet, luego IP, luego UDP y luego DNS. Abajo vemos todos los bits del mensaje, en forma hexadecimal.&lt;br /&gt;&lt;br /&gt;Nos podemos fijar, por ejemplo, en que la parte Ethernet hay un identificador que nos dice que el mensaje que contiene es IP (Type 0x0800). Asimismo, en el mensaje IP vemos que hay un identificador que nos dice que el mensaje que transporta es de tipo UDP (Protocol UDP: 0x11). Y que en el mensaje UDP, el puerto de origen &lt;a href="http://es.wikipedia.org/wiki/Anexo:Lista_de_n%C3%BAmeros_de_puerto"&gt;53 identifica el servicio&lt;/a&gt; que lo envía: DNS. La respuesta proporcionada por DNS es clara: &lt;i&gt;No such name&lt;/i&gt;: ese nombre solicitado, www.dimequenoexiste.com, no existe.&lt;br /&gt;&lt;br /&gt;Si hubiese pedido una página &lt;i&gt;html&lt;/i&gt; a un servidor HTTP, sería muy parecido. Pero gastaría TCP en vez de UDP, ya que hay que manejar mayor intercambio de información y es necesaria cierta coherencia en la comunicación. Y por encima de TCP gastaría HTTP. Pero el formato por debajo no cambiaría. &lt;br /&gt;&lt;br /&gt;Pues más o menos así funciona Internet (o así nos dicen que funciona). En general, el servicio proporcionado por los protocolos de transporte TCP o UDP se queda demasiado corto para aplicaciones, cada vez más usadas, de vídeo bajo demanda, televisión por Internet, videoconferencias... y es necesario ingeniar otros protocolos.&lt;br /&gt;&lt;br /&gt;Hasta IP se está quedando limitada. La nueva versión &lt;a href="http://es.wikipedia.org/wiki/IPv6"&gt;IPv6&lt;/a&gt; permite no sólo más direcciones en el mundo (las actuales se habrían acabado de no ser por ciertos trucos que hemos inventado) sino también permiten un sistema de prioridades y hasta soporte para reserva de ancho de banda. Es decir, identificar la importancia de la comunicación y darle un canal dedicado para mejorar la calidad de servicio. Pero poco a poco. Si ni siquiera esto nos lo enseñan en la carrera de Informática a todos los alumnos (depende de las intensificaciones), ¡menos aún voy a empezar por ahí en este blog!&lt;br /&gt;&lt;br /&gt;&lt;div class="footnotes" id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; He ocultado información acerca de las direcciones Ethernet e IP. No porque desconfíe de los lectores del blog. Es que hay mucha gente rara suelta en Internet.&lt;/div&gt;&lt;br /&gt;&lt;div class="sources"&gt;Enlaces del texto&lt;br /&gt;Captura realizada con &lt;a href="http://www.ethereal.com/"&gt;Ethereal&lt;/a&gt;, un conocido analizador de paquetes.&lt;/div&gt;&lt;br /&gt;&lt;a class="reltext" onclick="return Mostra('rel')"&gt;Posts relacionados&lt;/a&gt;&lt;br /&gt;&lt;div class="related" id="rel"&gt;&lt;a href="http://civada.blogspot.com/2007/09/csi-cmo-funciona-internet.html"&gt;Cómo funciona Internet (I)&lt;/a&gt;&lt;br /&gt;&lt;a href="http://civada.blogspot.com/2008/04/el-nilo-internet-y-los-fractales.html"&gt;El Nilo, Internet y los fractales&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150691805752037383-2108167592503849433?l=civada.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://civada.blogspot.com/feeds/2108167592503849433/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1150691805752037383&amp;postID=2108167592503849433" title="1 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/2108167592503849433" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/2108167592503849433" /><link rel="alternate" type="text/html" href="http://civada.blogspot.com/2007/10/csi-vii-cmo-funciona-internet-ii.html" title="CSI VII: Cómo funciona Internet (II)" /><author><name>Delirium</name><uri>http://www.blogger.com/profile/08408043740617685786</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_dk7-LG3RBOQ/Rw9Ty7QRuxI/AAAAAAAAAOc/zoklnC0273o/s72-c/EsquemaTCP-IP2.gif" height="72" width="72" /><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150691805752037383.post-6722004367594830437</id><published>2007-09-27T19:42:00.000+02:00</published><updated>2007-10-12T12:05:07.513+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Informática" /><title type="text">CSI VI: Cómo funciona Internet</title><content type="html">&lt;span style="font-size: 95%;"&gt;Vale, venga: hagamos una pregunta inocente: ¿cómo funciona Internet?. Por suerte, esta sí es una de las cosas que se estudian en Informática. Pero la pregunta no es tan sencillita, no. Primero: ¿qué significa Internet?. Según la Wikipedia:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Internet es un método de interconexión descentralizada de redes de computadoras implementado en un conjunto de protocolos denominado TCP/IP y garantiza que redes físicas heterogéneas funcionen como una red lógica única, de alcance mundial.&lt;/blockquote&gt;&lt;br /&gt;Aquí hay jerga de esa que tanto nos gusta. Este párrafo quiere decir más o menos que Internet sirve para comunicar distintos dispositivos con otros ordenadores. Descentralizado hace referencia a que no existe un supercomputador gigantesco en Arizona haciéndolo funcionar. Implementado en un conjunto de &lt;b&gt;protocolos&lt;/b&gt; nos dice simplemente que utilizamos ciertas formas de comunicarnos para entendernos unos a otros. Y garantiza que blablabla significa que los usuarios no tienen por qué conocer de qué manera se transmite la información. Eso para los Telecos.&lt;br /&gt;&lt;br /&gt;Así que vayámonos haciendo a la idea. Internet no es la WWW. Internet no es el eMule.  Internet no es Youtube. Internet no es la causa del bajo nivel del cine español, ni del cierre de los videoclubs, ni de que los niños no lean. Y por supuesto, no tiene nada que ver con el porno, &lt;a href="http://diariodeunjabali.com/archivos/categorias/cabreos/tom_cruise_e_internet_de_barman_a_iluminado.html"&gt;por más que Tom Cruise quiera&lt;/a&gt;. Otra cosa es que se vea porno a través de Internet&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="fullpost" style="font-size: 95%;"&gt;Vale. Tenemos la vaga idea de que Internet es un canal para comunicar información a través de una o muchas redes, sean del tipo que sean. Pero ¿cómo funciona?. Pues a ver: hagamos una prueba y construyamos Internet. Supongamos que Aitor le quiere pedir a Bartolo una foto. Como le han dicho en PC City que los cables Ethernet sirven para transportar datos le tira una punta del cable a Bartolo (B). Pero no nos sirve gritarle al cable. De alguna manera hemos de codificar el "quiero una foto" para transportar la petición por el cable. Cuidado. No me refiero a transformar las palabras "quiero una foto" en secuencias de 0s y 1s. Eso también se hace y para ello hay tablas (&lt;a href="http://es.wikipedia.org/wiki/Ascii"&gt;ASCII&lt;/a&gt; es la mas conocida). Me refiero a que &lt;i&gt;esos ceros y unos se codifican luego para enviarlos de cierta forma&lt;/i&gt;. Y con ciertos niveles de tensión. O transformándolos en ondas de cierta manera.&lt;br /&gt;&lt;br /&gt;Maneras de codificar/transformar/modular la información hay muchas. Dependen, fundamentalmente del medio a través del cual vayamos a enviarla. Y de lo que queramos hacer con ella. Por eso se definen muchas maneras de hacerlo según el &lt;b&gt;nivel físico&lt;/b&gt; por donde se va a enviar.&lt;br /&gt;&lt;br /&gt;Vale. Ahora imaginemos que B se dedica a repartir fotos. Y que todos los Colegas de la oficina estamos conectados al mismo cable y pedimos fotos a B. A B le llegan mensajes del tipo "quiero una foto", pero... ¿Cómo sabe B quién le ha pedido una foto?. Pues añadimos información de quién somos y a quién pedimos algo. Porque al estar todos conectados al mismo cable, ¡los mensajes los recibimos todos!. Hace falta indicar no sólo qué queremos, sino quiénes somos y a quién se lo pedimos. De este modo sabremos cuándo las respuestas o peticiones son para nosotros. Esta información que se añade no tiene nada que ver con la información que se podía añadir en la codificación. Esto es importante notarlo porque...&lt;br /&gt;&lt;br /&gt;Supongamos que en vez de un cable quiero transmitir la información de otra manera. A través de Wi-Fi, (para no gastar cables, por ejemplo). La información será de otro tipo (ondas electro-magnéticas)... y por tanto deberé codificar la información de la mejor manera para ese tipo de transmisión. Pero ¿por qué debería cambiar la manera que tenemos de identificarnos?. &lt;i&gt;Mantendremos independientes esos dos niveles&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;A esa idea tan buena y tan tonta se le llama estructurar en forma de pila. &lt;i&gt;Internet funciona en forma de pila de protocolos&lt;/i&gt;: hay partes de la comunicación (niveles) que tienen unas tareas específicas. Puedo idear muchas maneras adecuadas de realizar esas tareas... pero no es necesario cambiar el resto de "niveles". Constituye así una arquitectura flexible.&lt;br /&gt;&lt;br /&gt;Demos un paso más. Supongamos que queremos ofrecer ciertos servicios a otra oficina. Que ellos también quieren fotos. El problema es que ellos no tienen nombres como los nuestros (A, B, C): se llaman con números (1, 2, 3). Y... ¿le importa a B cómo se llamen ellos? Pues no. ¿Y si gastan telepatía para transmitirse entre ellos las imágenes? Tampoco nos importa. Lo único necesario es que existan unos nombres comunes &lt;i&gt;a todos nosotros&lt;/i&gt;: de este modo alguien de la otra oficina puede hacer una petición a B incluyendo su supernombre y B sabrá a quién tiene que contestar. &lt;br /&gt;&lt;br /&gt;Para encaminar bien los mensajes hacia otras oficinas existen unos elementos: se llaman &lt;i&gt;routers&lt;/i&gt;. Un &lt;i&gt;router&lt;/i&gt; debe encontrar al destinatario de un mensaje en la red donde opera. Y si no lo encuentra, redirigir ese mensaje a otro que quizá lo sepa. Un &lt;i&gt;router&lt;/i&gt; opera en el &lt;b&gt;nivel de red&lt;/b&gt;. Este nivel es el que es la clave de Internet. Las direcciones comunes a todos se llaman &lt;i&gt;direcciones IP&lt;/i&gt;. IP significa &lt;i&gt;Internet Protocol&lt;/i&gt;, en un dechado de imaginación.&lt;br /&gt;&lt;br /&gt;Entonces hagamos un repaso: transformamos la información de cierta manera, añadimos información para encontrarnos dentro de una red, le sumamos información para transmitirlo a otras redes. Además, en cada nivel añadimos más cosas. Por ejemplo para controlar que no ha habido ningún error en el envío. O para dar pistas sobre lo que contiene el mensaje, o el tipo de red desde donde se envía... en fin: un montón de cosas. Pero resumiendo: llevamos tres niveles. Y se llaman nivel físico, &lt;b&gt;nivel de enlace&lt;/b&gt; y nivel de red.&lt;br /&gt;&lt;br /&gt;Pero hay más. Resulta que en Internet no se envían los datos todos juntitos. Se envían por paquetes. De este modo podemos aprovechar mucho más toda la amplitud de la red. Unos paquetes de un mensaje se intercalan con los de otro. Cada paquete se busca la vida para llegar a su destino. ¿Qué es lo que pasa con este modelo?. Pues que cuando nos salimos de nuestra red o cable podemos tener problemas. A veces se pueden perder fragmentos, o llegar desordenados, o que algunos lleguen corruptos...&lt;br /&gt;&lt;br /&gt;Para controlar un poco todo este lío se añade un nivel o capa más: la capa contiene cierta información acerca de la comunicación que mantienen dos equipos. A esta capa se le llama &lt;b&gt;de transporte&lt;/b&gt;. De este modo podemos proporcionar &lt;i&gt;control de flujo&lt;/i&gt;, que no es más que cierta coherencia en la transmisión de la información. Podemos utilizar protocolos que garanticen mayor o menor control sobre la comunicación. En Internet se gasta un protocolo llamado &lt;b&gt;TCP&lt;/b&gt; (&lt;i&gt;Transmit Control Protocol&lt;/i&gt;). De ahí la definición anterior de la Wikipedia.&lt;br /&gt;&lt;br /&gt;¡Pero aún no hemos terminado! Supongamos que B ofrece muchos servicios, además de enviar fotos. Supongamos que, encima, te dice la hora, repite lo que dices o cada día te cita una frase famosa&lt;a href="#fn1"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;. Pues le pondremos un identificador a cada uno. Los servicios más conocidos tienen un identificador / &lt;b&gt;número de puerto bien conocido&lt;/b&gt; (por todos). Además, cada servicio o aplicación requiere de un protocolo de transporte u otro, según la necesidad de control sobre la transmisión que precise. Lo que se hace es añadir el identificador del servicio junto con la información de la capa de transporte. Y luego añadimos la información referida únicamente al servicio.&lt;br /&gt;&lt;br /&gt;Esta última capa se llama &lt;b&gt;de aplicación&lt;/b&gt;. En Internet, el protocolo más conocido en esta capa es HTTP. HTTP definía básicamente una manera de transmitir letras y la manera en que queremos que un programa navegante las muestre. El resultado son las páginas &lt;i&gt;html&lt;/i&gt;. Como la que vemos.&lt;br /&gt;&lt;br /&gt;Resumen, tenemos 5 niveles: físico, enlace, red, transporte y aplicación. Cada nivel añade información al siguiente, empezando desde el de aplicación. Añade la información que aquí he contado... y mucha más. Y la comunicación es muuuucho más compleja. Pero qué mas quieren. Si pudiese contar cómo funciona Internet en un post... debería preguntarme dónde fue a parar el dinero que invertí en la carrera. &lt;br /&gt;&lt;br /&gt;&lt;div class="footnotes" id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; Todos estos servicios existen y son &lt;i&gt;bien-conocidos&lt;/i&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="sources"&gt;Para saber de verdad cómo va esto: &lt;a href="http://es.wikipedia.org/wiki/TCP/IP"&gt;Wikipedia&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;a class="reltext" onclick="return Mostra('rel')"&gt;Posts relacionados&lt;/a&gt;&lt;br /&gt;&lt;div class="related" id="rel"&gt;&lt;a href="http://civada.blogspot.com/2007/10/csi-vii-cmo-funciona-internet-ii.html"&gt;Cómo funciona Internet (II)&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150691805752037383-6722004367594830437?l=civada.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://civada.blogspot.com/feeds/6722004367594830437/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1150691805752037383&amp;postID=6722004367594830437" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/6722004367594830437" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/6722004367594830437" /><link rel="alternate" type="text/html" href="http://civada.blogspot.com/2007/09/csi-cmo-funciona-internet.html" title="CSI VI: Cómo funciona Internet" /><author><name>Delirium</name><uri>http://www.blogger.com/profile/08408043740617685786</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150691805752037383.post-8446874137740389983</id><published>2007-09-02T12:10:00.001+02:00</published><updated>2008-09-03T10:14:45.937+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Informática" /><title type="text">Seguir leyendo (2º bobo-tutorial)</title><content type="html">&lt;span style="font-size:95%;"&gt;Como verán, he estado trasteando los últimos días con el &lt;i&gt;template&lt;/i&gt; del blog. Para tener una sección con las referencias, pies de página, con su propio estilo. Y luego para conseguir un cuadro desplegable en el que ubicar los posts relacionados a cada artículo. Como salió, me sentí fuerte, poderoso e informático y decidí conseguir que la página principal del blog mostrase sólo el inicio de los posts, junto con una enlace "Seguir leyendo" al post completo.&lt;br /&gt;&lt;br /&gt;Lo he conseguido. Pero el mérito no es mío, ya que al final copié. De &lt;a href="http://hackosphere.blogspot.com/2006/11/selective-expandable-posts.html"&gt;Hackosphere&lt;/a&gt;, para ser más exactos, que es un blog de donde puedo aprender bastante para ir jugando. Como no tiene mucho sentido que yo vuelva a explicar el procedimiento que ya explica el autor del "truco" (aunque luego veremos que algo de sentido sí tiene), casi mejor explico por qué funciona y qué es lo que intenté hacer yo. Así de paso comento un poco lo que he aprendido.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="fullpost"  style="font-size:95%;"&gt;Vale. Lo primero que hice fue bajar la página principal de mi blog y el &lt;i&gt;template&lt;/i&gt;. Quería comparar la estructura de la página con el &lt;i&gt;template&lt;/i&gt;. Sabiendo qué tendría que cambiar en la página .html para conseguir mis objetivos podría identificar en qué lugar del &lt;i&gt;template&lt;/i&gt; debía realizar los cambios. Fácil y sencillo si cuentas con un editor de HTML (Dreamweaver, por ejemplo).&lt;br /&gt;&lt;br /&gt;Encontré que todos los posts de la página principal se ubicaban en unas "divisiones" del texto, llamadas &lt;b&gt;post-body&lt;/b&gt;. Los contenedores básicos de HTML se marcan con la etiqueta &amp;lt;div&amp;gt;. Al buscar &lt;i&gt;post-body&lt;/i&gt; en el &lt;i&gt;template&lt;/i&gt; encontré una única linea: la que buscaba.&lt;br /&gt;&lt;div class="code"&gt;&amp;lt;DIV class='post-body'&amp;gt;&lt;br /&gt;&amp;lt;P&amp;gt;&amp;lt;data:post.body/&amp;gt;&amp;lt;/P&amp;gt;&lt;br /&gt;&amp;lt;DIV style='clear: both;'/&amp;gt; &lt;br /&gt;&amp;lt;/DIV&amp;gt;&lt;br /&gt;&amp;lt;DIV class='post-footer'&amp;gt;&lt;/div&gt;&lt;br /&gt;Esto ya es el pie, donde pone el autor, hora...&lt;br /&gt;&lt;br /&gt;Entendía poco, pero lo suficiente para saber que &lt;b&gt;data:post.body&lt;/b&gt; es información que guarda Blogger y hace referencia al contenido completo de post. Bueno, lo primero que hice fue añadir una sección bajo el post (que incluiría la referencia al post entero), aunque ésta &lt;b&gt;sólo&lt;/b&gt; debía aparecer en la página principal y no en el resto. ¿Cómo se hace eso?. Pues de la misma manera que se hace con los comentarios. Tiene que haber una condición antes de los comentarios que indique si estamos o no en la página principal. La encontré, y, añadiendo la información de la referencia a la entrada (que aparece en todo título de Blogger Beta), la cosa quedó así:&lt;br /&gt;&lt;div class="code"&gt;&amp;lt;b:if cond='data:blog.pageType != "item"'&amp;gt;&lt;br /&gt;&amp;lt;A expr:href='data:post.url'&amp;gt;Ver el resto de la entrada&amp;lt;/A&amp;gt;&lt;br /&gt;&amp;lt;/b:if&amp;gt;&lt;/div&gt;&lt;br /&gt;Lo siguiente era conseguir: a) limitar la información que Blogger enviaba a la página o b) limitar el tamaño del párrafo y ocultar la información de sobra. Como de la a) no tenía ni repajolera idea, intenté la b. Lo único que se me ocurrió fue "tapar" esa información con las siguientes secciones, poniéndolas "encima" (para eso está el atributo &lt;a href="http://xhtml.com/en/css/reference/z-index/"&gt;z-index&lt;/a&gt; de las hojas de estilo). De todos modos parte de los post tenían que ser tapados por los siguientes post con partes visibles... y otras ocultas, así que la cosa no tenía solución. No encontré nada en HTML ni en las hojas de estilo que me ayudara.&lt;br /&gt;&lt;br /&gt;Y es que la solución venía a través de funciones Javascript, según me enteré al leer el post de Hackosphere, que invitaba a copiar al &lt;i&gt;template&lt;/i&gt; &lt;a href="http://rarunach.googlepages.com/hackosphere.js.html"&gt;esto&lt;/a&gt;. Las funciones Javascript son funciones en un sencillo lenguaje de programación desde las que se puede hacer referencia a elementos del documento HTML. Como programación "normal" pero gastando los identificadores de los elementos HTML para utilizarlos como variables.&lt;br /&gt;&lt;br /&gt;Para nuestro caso, lo que queremos es que una parte del documento quede visible en ciertas circunstancias. Para ello deberemos dividir los posts en dos "partes". Esta era la clave, en la que no había pensado (pese haber hecho algo parecido para mostrar y ocultar los posts relacionados). Las partes en que dividiremos el post serán estas:&lt;br /&gt;&lt;div class="code"&gt;Aquí va la entradilla&lt;br /&gt;&amp;lt;span id="fullpost" &amp;gt;A partir de aquí va el resto del código&amp;lt;span&amp;gt;&lt;/div&gt;&lt;br /&gt;Como se ve, hemos gastado el elemento &lt;a href="http://xhtml.com/en/xhtml/reference/span/"&gt;&amp;lt;span&amp;gt;&lt;/a&gt; y hemos identificado el resto del código, llamándolo &lt;b&gt;fulltext&lt;/b&gt; (aunque sería más apropiado llamarle &lt;i&gt;restoftext&lt;/i&gt;). Lo que haremos ahora es ocultar esta parte en la página principal. Eso se hace modificando, desde el &lt;i&gt;template&lt;/i&gt; el propio código de la página, cosa que yo tampoco sabía que se podía hacer. Pongo el código y explico qué es cada cosa:&lt;br /&gt;&lt;div class="code"&gt;/*aquí añadimos un identificador del post a la sección*/&lt;br /&gt;&amp;lt;div class='post-body' expr:id='"post-" + data:post.id'&amp;gt;&lt;br /&gt;/*Si no se trata de la página principal...*/&lt;br /&gt;&amp;lt;b:if cond='data:blog.pageType == "item"'&amp;gt;&lt;br /&gt;/*la sección fullpost del documento se mostrará &lt;a href="http://xhtml.com/en/css/reference/display/"&gt;inline&lt;/a&gt;*/&lt;br /&gt;&amp;lt;style&amp;gt;#fullpost{display:inline;}&amp;lt;/style&amp;gt;&lt;br /&gt;/*Este es el artículo*/&lt;br /&gt;&amp;lt;p&amp;gt;&amp;lt;data:post.body/&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;/*Si estamos en la página principal...*/&lt;br /&gt;&amp;lt;b:else/&amp;gt;&lt;br /&gt;/*la sección fullpost no se mostrará...*/&lt;br /&gt;&amp;lt;style&amp;gt;#fullpost{display:none;}&amp;lt;/style&amp;gt;&lt;br /&gt;/*...pero el post sigue estando ahí, enterito!*/&lt;br /&gt;&amp;lt;p&amp;gt;&amp;lt;data:post.body/&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;/*Este es el link al artículo completo*/&lt;br /&gt;&amp;lt;span id='showlink' style='font-size:80%;'&amp;gt;&lt;br /&gt;&amp;lt;a expr:href='data:post.url'&amp;gt;Seguir leyendo &amp;lt;/a&amp;gt;&lt;br /&gt;&amp;lt;/span&amp;gt;&lt;br /&gt;/*Y esta es la función que no muestra el enlace si el post no tiene fulltext*/&lt;br /&gt;&amp;lt;script type='text/javascript'&amp;gt;&lt;br /&gt;            checkFull(&amp;amp;quot;post-&amp;amp;quot; + "&amp;lt;data:post.id/&amp;gt;&amp;amp;quot;);&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;/b:if&amp;gt;&lt;/div&gt;&lt;br /&gt;Y ya está. Y si alguien, por casualidad, se ha molestado en leer el post de donde sale el truco, se preguntará (con toda la razón del mundo): ¿y para qué leches valen las funciones Javascript &lt;i&gt;hideFull&lt;/i&gt; y &lt;i&gt;showFull&lt;/i&gt;?. Pues para nada, al menos en mi blog. En realidad sirven para mostrar y ocultar el texto entero del post &lt;i&gt;en la página principal&lt;/i&gt;. Y como eso no era lo que quería, no he copiado estas funciones a mi &lt;i&gt;template&lt;/i&gt;. Me juego un pie que más de uno las tiene en su blog, cargándolas cada vez que visita la página principal sin gastarlas. Hay un errorcillo, y es que al visitar las entradas anteriores en la página principal (que no tienen entradilla y &lt;i&gt;fulltext&lt;/i&gt;) sigue apareciendo el enlace a la entrada completa, pero tampoco me preocupa demasiado.&lt;br /&gt;&lt;br /&gt;De todos modos, aunque me habría gustado hacer todo este proceso yo sólo, también es importante haber aprendido más cosas. Ahora que entiendo cómo funciona un poco todo este tema podré trastear un poco más con Blogger, al cual le estoy cogiendo cariño.&lt;br /&gt;&lt;br /&gt;&lt;div class="sources"&gt;&lt;a href="http://xhtml.com/en/css/reference/"&gt;CSS Reference&lt;/a&gt;. Lista de atributos CSS.&lt;br /&gt;&lt;a href="http://xhtml.com/en/xhtml/reference/"&gt;XHTML Reference&lt;/a&gt;. Para saber qué es lo que compone las páginas.&lt;br /&gt;&lt;a href="http://www.w3c.es/Divulgacion/Guiasbreves/XHTML"&gt;Guía breve de XHTML&lt;/a&gt;. En castellano.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;a class="reltext" onclick="return Mostra('rel')"&gt;Posts relacionados&lt;/a&gt;&lt;div class="related" id="rel"&gt;&lt;a href="http://civada.blogspot.com/2007/08/1er-bobo-tutorial-ensanchecer-blogger.html"&gt;Ensanchecer Blogger&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150691805752037383-8446874137740389983?l=civada.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://civada.blogspot.com/feeds/8446874137740389983/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1150691805752037383&amp;postID=8446874137740389983" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/8446874137740389983" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/8446874137740389983" /><link rel="alternate" type="text/html" href="http://civada.blogspot.com/2007/09/seguir-leyendo-2-bobo-tutorial.html" title="Seguir leyendo (2º bobo-tutorial)" /><author><name>Delirium</name><uri>http://www.blogger.com/profile/08408043740617685786</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150691805752037383.post-1583563248919609140</id><published>2007-08-25T10:07:00.000+02:00</published><updated>2007-09-01T20:40:35.018+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Informática" /><title type="text">CSI V: Evolución de los SO (II)</title><content type="html">&lt;span style="font-size:95%;"&gt;En el capítulo anterior... la II Guerra Mundial impulsó toda una serie de nuevas tecnologías y dio un notable empujón a la ciencia de la computación. A finales de los años 70 ya existían sistemas capaces de compartir los recursos físicos de las máquinas de cómputo a varios procesos en ejecución, para los cuales se empezaban a crear cada vez más sofisticados lenguajes de programación. Cada proceso actuaba como si fuese el único que se estaba ejecutando y el intercambio de procesos era tan rápido que permitía al usuario interaccionar con el sistema.&lt;br /&gt;&lt;br /&gt;Y no sólo eso, el &lt;i&gt;tiempo compartido&lt;/i&gt; abrió la posibilidad a que varios usuarios pudiesen ejecutar sus programas sobre la misma máquina. Hasta entonces sólo un usuario podía interactuar con ella, sentado frente a un terminal. Con la opción de &lt;b&gt;multiusuario&lt;/b&gt; se extendían las posibilidades.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span id="fullpost" style="font-size:95%;"&gt;Todo esto conllevaba grandes retos: como los programas se almacenaban en disco, es necesario una gestión de memoria de modo que se puedan traer procesos de dondequiera que estén almacenados a la memoria principal que gasta el procesador. La solución consistió en crear jerarquías de memoria, donde las más pequeñas son las más rápidas y están más cerca del procesador. Las técnicas que se emplearon crearon el concepto de &lt;b&gt;memoria virtual&lt;/b&gt;. La memoria virtual permite, en esencia, que el programa sea más grande que la memoria física.&lt;br /&gt;&lt;br /&gt;Como los programas escribían sus resultados en disco en vez de directamente en impresora o cinta, era necesario inventar alguna gestión de archivos. Los &lt;b&gt;sistemas de archivos&lt;/b&gt; se encargaron de organizar e indexar todos los distintos archivos que estaban en en los discos. Y, si hay varios discos, ¡también tiene que encargarse de mantener y ofrecer una visión coherente por encima de estos!.&lt;br /&gt;&lt;br /&gt;Y como hay muchos trabajos o tareas que se ejecutan "a la vez" entonces tenemos que incluir un sistema de gestión de tareas. Porque aunque cada una piense que ella es la única, muchas veces requiere de los resultados de otra. De quién le da igual; de eso se tienen que ocupar los &lt;b&gt;esquemas de planificación&lt;/b&gt; de la CPU. Ordenar la ejecución de muchas tareas estableciendo un orden y una asignación de recursos tal que no se produzcan &lt;i&gt;interbloqueos&lt;/i&gt; es otra de las muchas tareas del sistema operativo moderno. Todas estas funciones son complejas de realizar, pero muy fáciles de explicar y algún día las veremos.&lt;br /&gt;&lt;br /&gt;Pero volvamos a la historia, que aún no ha terminado. Porque hasta ahora no hemos hablado del trasto que tenemos junto a nosotros, al cual llamamos PC&lt;a href="#fn1" title="Ir al pie"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; (o &lt;i&gt;pasokon&lt;/i&gt; si por casualidad hablamos japonés).&lt;br /&gt;&lt;br /&gt;Aquí hay dos caminos distintos. Por una lado la evolución de lo que es la propia máquina. En ese sentido podemos decir que los computadores personales descienden de las calculadoras. La historia de la creación de los PC es muy entretenida por ese camino: hay bancarrotas, ladrones de ideas, oportunistas, genios de las computadoras y genios de las promociones. Algún día la contaré, aunque no se estudia directamente en la carrera.&lt;br /&gt;&lt;br /&gt;Por otro lado está la evolución del sistema operativo. Los sistemas operativos de los PC no eran multiusuario ni multitarea cuando nacieron. El bajo coste del &lt;i&gt;hardware&lt;/i&gt; no urgía de un aprovechamiento exhaustivo de éste y su reducido tamaño justificaba el uso de un sólo usuario. Algunas de las características de sistemas grandes no se aplicaron a los computadores personales. Por ejemplo, en principio se pensó que no era necesario un sistema de protección de archivos en computadores personales. Los virus chungos (que los informáticos llamamos &lt;i&gt;programas maliciosos&lt;/i&gt;) demostraron lo contrario.&lt;br /&gt;&lt;br /&gt;Pero otras muchas características de los macrocomputadores sí fueron utilizadas para gestionar PCs. El ejemplo más claro de esto es el sistema operativo &lt;a href="http://es.wikipedia.org/wiki/Multics"&gt;MULTICS&lt;/a&gt;, desarrollado entre 1965 y 1970 en el MIT, que se ejecutaba en un monstruo (GE 645). Muchas de las ideas fueron tomadas de MULTICS cuando &lt;a href="http://en.wikipedia.org/wiki/Dennis_Ritchie"&gt;Dennis Ritchie&lt;/a&gt; y &lt;a href="http://en.wikipedia.org/wiki/Ken_Thompson"&gt;Ken Thompson&lt;/a&gt; desarrollaron &lt;a href="http://es.wikipedia.org/wiki/Unix"&gt;UNIX&lt;/a&gt; para un "mini" computador PDP. A lo largo de los años 80 UNIX incorporó mecanismos de seguridad, multitarea y multiusuario que han sido tomados por muchos sistemas posteriores. Hay más de 100 sistemas operativos basados en UNIX en los últimos 20 años.&lt;br /&gt;&lt;br /&gt;Por otro lado, IBM modernizó su primer sistema operativo para PCs, &lt;a href="http://es.wikipedia.org/wiki/MS-DOS"&gt;MS-DOS&lt;/a&gt;, y creó &lt;a href="http://es.wikipedia.org/wiki/OS/2"&gt;OS/2&lt;/a&gt;, lo que terminó en una crónica de un fracaso en la lucha contra Microsoft. OS/2 incorporaba ya multitarea. Microsoft, que mantuvo los derechos sobre su código para el primer PC de IBM, realizó su carrera en solitario en los 80. Tanto Windows 1.0 como 2.0 eran poco más que aplicaciones corriendo sobre MS-DOS, permitiendo, eso sí, la multitarea (MS-DOS no era multitarea ni multiusuario). Windows 3.0 ya incorporó gestión de memoria virtual. Hoy en día Windows acapara cerca del 90% de sistemas operativos del mundo.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Otro tipo de sistemas&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Pero no nos perdamos. Los sistemas operativos están para más cosas que para bajarse música. Los hay que tienen que gestionar cálculos extremadamente grandes. Una solución consiste en utilizar muchos procesadores juntos. Un sistema con muchos procesadores incrementa sus prestaciones, pero requiere de una gestión mucho más compleja. A veces los &lt;b&gt;sistemas paralelos&lt;/b&gt; comparten memoria u otros periféricos. A veces no. Hay que gestionar con cuidado las escrituras y lecturas de memoria cuando hay varios procesadores que las gastan porque, por ejemplo, podríamos leer una copia de un dato que actualmente está siendo modificado por otro procesador.&lt;br /&gt;&lt;br /&gt;A veces hay muchos ordenadores distantes, cada uno con sus cosillas, ejecutando una tarea conjunta. A esto se le llama &lt;b&gt;sistemas distribuidos&lt;/b&gt;. Los sistemas distribuidos suelen tener un sistema operativo "normal", pero por encima de él hay una capa de servicios relacionados con la gestión del sistema distribuido.&lt;br /&gt;&lt;br /&gt;Otras veces es necesario imponer serias restricciones al tiempo en que deben ejecutarse ciertas tareas, como en entornos industriales. Para esto existen &lt;b&gt;sistemas de tiempo real&lt;/b&gt;. A veces nos interesa que los errores que se puedan producir no detengan el sistema, sino que lo &lt;i&gt;degraden&lt;/i&gt; de forma aceptable: buscamos &lt;b&gt;sistemas tolerantes a fallos&lt;/b&gt;. En fin, las distintas necesidades determinan el tipo sistema que gastaremos.&lt;br /&gt;&lt;br /&gt;Y yo no necesito más que Windows &lt;s&gt;pirateado&lt;/s&gt;. Y por eso gasto Windows. Queda pues, contestada la pregunta que me hacía yo mismo.&lt;br /&gt;&lt;div class="footnotes" id="fn1"&gt;&lt;br /&gt;&lt;sup&gt;1&lt;/sup&gt; Jamás entenderé por qué la RAE acepta &lt;a href="http://buscon.rae.es/draeI/SrvltGUIBusUsual?LEMA=cederr%C3%B3n&amp;TIPO_HTML=2&amp;amp;FORMATO=ampliado&amp;amp;sourceid=mozilla-search"&gt;cederrón&lt;/a&gt; y no &lt;i&gt;pecé&lt;/i&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="sources"&gt;Sistemas Operativos. Addison Wesley Longman. ISBN 0-201-59113-8&lt;/div&gt;&lt;br /&gt;&lt;a class="reltext" onclick="return Mostra('rel')"&gt;Posts relacionados&lt;/a&gt;&lt;br /&gt;&lt;div class="related" id="rel"&gt;&lt;a href="http://civada.blogspot.com/2007/08/csi-iv-evolucin-de-los-so.html"&gt;Evolución de los Sistemas Operativos&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150691805752037383-1583563248919609140?l=civada.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://civada.blogspot.com/feeds/1583563248919609140/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1150691805752037383&amp;postID=1583563248919609140" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/1583563248919609140" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/1583563248919609140" /><link rel="alternate" type="text/html" href="http://civada.blogspot.com/2007/08/csi-v-evolucin-de-los-so-ii.html" title="CSI V: Evolución de los SO (II)" /><author><name>Delirium</name><uri>http://www.blogger.com/profile/08408043740617685786</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150691805752037383.post-8218009576844988318</id><published>2007-08-10T21:20:00.000+02:00</published><updated>2007-09-03T20:46:14.303+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Informática" /><title type="text">CSI IV: Evolución de los SO</title><content type="html">&lt;span style="font-size:95;"&gt;Yo gasto Windows. Uf, ¡que vergüenza para un informático!, ¿no?. Se supone que debería saber gastar alguno tipo UNIX, de código libre, haber añadido un par de llamadas al sistema y compilarlo... Pues no, no sé, por más que se haga en la carrera. Y gasto Windows porque... porque... porque aceptamos Windows como sistema operativo.&lt;br /&gt;&lt;br /&gt;Y de eso va el tema de hoy en Cosas que SÍ se enseñan en Informática: qué es y para qué sirve un SO. Y lo haremos a través de su historia.&lt;br /&gt;&lt;br /&gt;Un Sistema Operativo es aquello que da sentido al cacharro lleno de cables, tarjetas y discos que tenemos como ordenador. Sabemos que tenemos una CPU dentro, un monitor, un ratón, uno o varios discos duros, lector de DVDs... un montón de cosas que se llaman Hardware. Sabemos que tenemos la mula descargando Pitch Black (yo no), el reproductor sonando, la sesión del hermano abierta... un montón de cosas que llamamos Software. ¿Quién se encarga de repartir los recursos limitados de la maquinaria entre todos los programas que se están ejecutando?. No, no es Aitor Menta, aunque podría. Es el Sistema Operativo.&lt;br /&gt;Pero esto no ha sido siempre así...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="fullpost" style="font-size:95;"&gt;Buceemos un poquito en el pasado. La informática remotamente parecida a lo que conocemos nació en los años 40. Había una guerra y era necesario calcular las trayectorias de los misiles. Parece que hay pocas cosas como la guerra para agudizar el ingenio. Las grandes máquinas de calcular solían diseñarse para un único propósito. Para el resto estaban las calculadoras. Los datos de entrada de los computadores se proporcionaban mediante tarjetas perforadas y el resultado se escribía en cintas magnéticas o imprimía. Existía la sensación de que algo más podía hacerse con esos trastos tan grandes.&lt;br /&gt;&lt;br /&gt;Pero entre las muchas personas trabajando en los EE.UU. había un luminaria: &lt;a href="http://es.wikipedia.org/wiki/John_von_Neumann"&gt;John von Neumann&lt;/a&gt;&lt;a href="#fn1" title="Nota al pie"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;. A él se le atribuye una idea magistral al colaborar en el diseño de una gran computadora, el &lt;a href="http://es.wikipedia.org/wiki/EDVAC"&gt;EDVAC&lt;/a&gt;: cada máquina podrá entender una serie de operaciones y tomará como entrada una serie de instrucciones (programa) a ejecutar secuencialmente. Casi simultáneamente otro genio que condujo a su país a reventar la superioridad alemana en las transmisiones lleva un tiempo pensando en eso. Su nombre es &lt;a href="http://es.wikipedia.org/wiki/Alan_Mathison_Turing"&gt;Alan Turing&lt;/a&gt;&lt;a href="#fn1" title="Nota al pie"&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;. A finales de los 40 en un congreso en Manchester afirmó: "Estamos intentando construir una máquina que haga todo tipo de cosas diferentes simplemente programándola, en vez de añadiendo aparatos extra".&lt;br /&gt;&lt;br /&gt;Bien, a ello se le llamó &lt;b&gt;programa residente&lt;/b&gt;: la máquina ejecuta un código proporcionado desde fuera en algún lenguaje. Si en la memoria de la máquina se encuentran tanto los datos que necesite el programa como el código a ejecutar, se llama &lt;a href="http://es.wikipedia.org/wiki/Arquitectura_von_Neumann"&gt;Arquitectura von Neumann&lt;/a&gt; y hoy subsiste como la base de la informática moderna. Hay quien opina que von Neumann inventó el concepto de software, aunque esto quizá sea ir demasiado lejos.&lt;br /&gt;&lt;br /&gt;Los programas de entonces solían ser cálculos matemáticos, junto con algunas instrucciones sencillas: ahora calcular, ahora detenerse, ahora escribir en una cinta el resultado, ahora leer más datos. El usuario introducía unas tarjetas perforadas que el computador leía. Cuando en los años 50 apareció el lenguaje &lt;a href="http://es.wikipedia.org/wiki/Fortran"&gt;FORTRAN&lt;/a&gt; (el padre de todos los lenguajes), esta técnica mejoró mucho, pero seguía siendo muy pesada y requería al dos personas: el programador y el técnico. En seguida se dieron cuenta que podían acelerar el proceso agrupando las tareas en lotes con necesidades similares. A estos sistemas se les conoce como &lt;b&gt;sistemas por lotes sencillos&lt;/b&gt;. El sistema operativo -&lt;i&gt;monitor residente&lt;/i&gt;- se limitaba a transferir el control de un proceso al siguiente.&lt;br /&gt;&lt;br /&gt;Uno de sus problemas era que el tiempo en que tardaban en leerse las tarjetas y en escribir resultados era demasiado lento. Los dispositivos de E/S son infinitamente más lentos que los procesadores y más si los primeros son mecánicos. La cosa mejoró con la introducción de discos magnéticos. Así, las tarjetas se escribían en discos y el sistema operativo creaba una "tabla" para cada proceso en disco. Lo mismo se hizo con la salida: en vez de escribir a la cinta o impresora se escribía en disco. Luego, al finalizar el trabajo, se escribía todo el resultado. A esto se le llamó &lt;b&gt;spooling&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;El &lt;i&gt;spooling&lt;/i&gt; dio origen a algo mucho más interesante: la reserva y planificación de trabajos. En disco podían mantenerse varias tareas esperando a ser ejecutadas. Es decir, pueden ejecutarse en un orden distinto y variable. Algo así permite que mientras un proceso realiza una larga operación de entrada o salida, &lt;i&gt;otro esté ejecutándose&lt;/i&gt;. Por tanto el "SO" ya tiene más curro: escoger una tarea para ejecutar. Esto incluye escoger las tareas para copiar a memoria si hay muchas y escoger de entre las tareas listas en memoria cual ejecutar. Como podemos tener potencialmente muchas tareas es necesario también gestionar la memoria. De nombre le pusieron &lt;b&gt;sistemas por lotes multiprogramados&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;Tomemos nota que en este punto el usuario tenía un papel pasivo: ¡no podía hacer nada nada mientras los programas se ejecutaban!. El tiempo de respuesta de los sistemas por lotes multiprogramados solía ser largo, pero ¿y si se deseaba realizar muchas acciones cortas? ¿Y si el usuario necesitara interactuar, proporcionar datos al programa mientras se ejecutaba?. Bien, esto sólo se pudo hacer cuando la conmutación entre trabajos se hizo mucho más frecuente, tanto, que daba la imagen de que todas las tareas se ejecutaban "al mismo tiempo". A esto se le conoce como &lt;b&gt;sistemas multitarea&lt;/b&gt; o de &lt;b&gt;tiempo compartido&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;De este modo se genera la ilusión de que un programa puede estar esperando al usuario, cuando en realidad pasan otras muchas cosas por la CPU en ese instante. La idea de tiempo compartido ya había surgido en los años 60, pero no fue hasta principios de la década de los 70 cuando pudo ponerse en marcha. El &lt;a href="http://en.wikipedia.org/wiki/OS_360"&gt;OS/360 de IBM&lt;/a&gt; de 1964 (IBM fue pionera en el desarrollo de grandes computadores) era originalmente un sistema por lotes, el cual se modificó para añadir la opción de tiempo compartido.&lt;br /&gt;&lt;br /&gt;Y aquí lo dejamos por el momento. Por supuesto: continuará...&lt;br /&gt;&lt;div class="footnotes" id="fn1"&gt;&lt;br /&gt;&lt;sup&gt;1&lt;/sup&gt; Aunque me gustaría hablar de lo extraordinario que era John von Neumann, ya lo han hecho otros, y seguro que mejor que yo. &lt;a href="http://www.historiasdelaciencia.com/?p=19"&gt;Aquí&lt;/a&gt; lo hace Omalaled. Y &lt;a href="http://www.historiasdelaciencia.com/?p=63"&gt;aquí&lt;/a&gt;. Y &lt;a href="http://www.historiasdelaciencia.com/?p=182"&gt;aquí&lt;/a&gt;.&lt;br /&gt;&lt;sup&gt;2&lt;/sup&gt; Lo mismo que antes. Sin embargo &lt;a href="http://www.historiasdelaciencia.com/?p=30"&gt;aquí&lt;/a&gt; se ha quedado un poco corto en la importancia que tuvo y su triste muerte. A ver si algún día hablo de Alan Turing y cuento más cosas.&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150691805752037383-8218009576844988318?l=civada.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://civada.blogspot.com/feeds/8218009576844988318/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1150691805752037383&amp;postID=8218009576844988318" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/8218009576844988318" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/8218009576844988318" /><link rel="alternate" type="text/html" href="http://civada.blogspot.com/2007/08/csi-iv-evolucin-de-los-so.html" title="CSI IV: Evolución de los SO" /><author><name>Delirium</name><uri>http://www.blogger.com/profile/08408043740617685786</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1150691805752037383.post-4562420725488958932</id><published>2007-08-05T13:54:00.001+02:00</published><updated>2009-05-31T12:07:37.722+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Informática" /><title type="text">1er bobo-tutorial: ensanchecer Blogger</title><content type="html">&lt;span style="font-size:95;"&gt;Como diría &lt;a href="http://en.wikipedia.org/wiki/List_of_recurring_characters_from_The_Simpsons#Jebediah_Springfield"&gt;Jedebiah Springfield&lt;/a&gt;, he &lt;i&gt;ensanchecido&lt;/i&gt; el blog. Y es que una de las cosas que menos me gustaba del diseño por defecto es el espacio de escritura en una estrecha columna central, dejando amplios márgenes a los lados inservibles. ¿A qué se debe esto? No lo sé. Sea cual sea la respuesta, otros diseños (blogs de &lt;a href="http://wordpress.org/"&gt;Wordpress&lt;/a&gt;, por ejemplo) no parecen considerarla. El diseño tradicional de Blogger está bien si lo que se pretende es publicar un vídeo y decir: "¿Qué os parece?", pero cuando los escritos sobrepasan las 1000 palabras los posts quedan demasiado largos y para evitarlo hay que a) ponerlo a letra muy pequeña o b) aprender a cambiar el diseño.&lt;br /&gt;&lt;br /&gt;Yo he venido optado por la opción a). Pero como me daba un poco de vergüenza ser informático y no intentar al menos aprender cómo funcionaba esto, me he puesto manos a la obra. Y bien, ya he entendido como funcionan los diseños o &lt;i&gt;templates&lt;/i&gt; de Blogger. Bueno, he entendido cómo funciona el diseño de MI página, que puede no ser el mismo para otros diseños que Blogger ofrece. De todos modos un buen diseño debe poder permitir cambiar el aspecto general realizando pocos cambios, así que no debe ser muy difícil &lt;i&gt;ensanchecer&lt;/i&gt; otros blogs.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="fullpost" style="font-size:95;"&gt;Para ponerme a prueba, he decidido ensanchar los márgenes de un blog amigo (El Rincón de Pinar). Con un poco de idea, Dreamweaver 8 (vale cualquier editor de texto) y &lt;a href="http://www.gimp.org/"&gt;Gimp2&lt;/a&gt; (aceptamos Paintbrush) en menos de 10 minutos he &lt;i&gt;ensanchecido&lt;/i&gt; el mismo. Y como me aburro, explico cómo. Quizá haya mejores tutoriales en la red para hacer lo mismo. Creo que &lt;a href="http://www.google.com/search?hl=en&amp;q=%22tutorial+acerca+de+c%C3%B3mo+ensanchecer+un+blog%22&amp;amp;btnG=Search" title="Búsqueda Google"&gt;no&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Empecemos por el sentido común y leemos el código del &lt;i&gt;template&lt;/i&gt;&lt;a href = "#fn2" title="Ir al pie"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;. Vemos que hacia el principio pone algo como &lt;i&gt;layout&lt;/i&gt;. Buscamos &lt;a href="http://www.wordreference.com/es/translation.asp?tranword=layout&amp;sourceid=Mozilla-search"&gt;&lt;i&gt;layout&lt;/i&gt;&lt;/a&gt;. Vemos que significa diseño o composición... pues por ahí tenemos que toquitear.&lt;br /&gt;&lt;div class="code"&gt;/* layout&lt;br /&gt;----------------------------------------------- */&lt;br /&gt;#outer-wrapper {&lt;br /&gt;margin: 0 auto;&lt;br /&gt;width: 760px;&lt;br /&gt;text-align: left;&lt;br /&gt;font: $bodyFont;&lt;br /&gt;}&lt;/div&gt;&lt;br /&gt;&lt;i&gt;Width&lt;/i&gt; significa anchura. La anchura de &lt;i&gt;outer-wrapper&lt;/i&gt; (envoltorio externo, es decir lo de más de fuera) es 760 loquesea (px significa pies xuntos para nuestros propósitos). Como queremos que sea más grande, ponemos 900 pies xuntos. Como se ve, no hace falta tener ni idea de informática. Por eso hay tantos tutoriales en linea de informática. Sigamos, empero, con el nuestro.&lt;br /&gt;&lt;div class="code"&gt;#content-wrapper {&lt;br /&gt;position: relative;&lt;br /&gt;width: 760px;&lt;br /&gt;background: #f7f0e9 url(http://www.blogblog.com/thisaway/bg_main_wrapper.gif) repeat-y left top;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;#main-wrapper {&lt;br /&gt;display: inline; /* fixes a strange ie margin bug */&lt;br /&gt;float: left;&lt;br /&gt;margin: 0 0 0 3px;&lt;br /&gt;padding: 0;&lt;br /&gt;width: 483px;&lt;br /&gt;word-wrap: break-word; /* fix for long text breaking sidebar float in IE */&lt;br /&gt;overflow: hidden;     /* fix for long non-text content breaking IE sidebar float */&lt;br /&gt;}&lt;/div&gt;&lt;br /&gt;&lt;i&gt;Content&lt;/i&gt; es contenido. El envoltorio del contenido también medía 760px. Ya sabemos que ahora tiene que medir 900. El &lt;i&gt;main-wrapper&lt;/i&gt; es el envoltorio principal. Ahí se enmarcan nuestros posts. Como queremos hacerlos más grandes, lo cambiamos a 600px. Para esto es necesario hacerse con una calculadora: 760 es a 483 como 900 a x. Yo he puesto 600px porque no gasto calculadora.&lt;br /&gt;&lt;br /&gt;Ya hemos acabado. Si ahora salvamos y vemos qué pasa (las pruebas mejor hacerlas en una página en el disco duro), veremos que muy posiblemente, no hemos acabado. Los colores y lineas no cuadran con el texto. La gracia está en que las imágenes que dan color y ornamentan el blog están pensadas para unos tamaños determinados. Por eso no basta con cambiar el tamaño de los márgenes: debemos adecuar las imágenes a los nuevos tamaños. Generalmente estas imágenes corresponden a la cabecera y pie del blog y algún tipo de imagen que separe el texto (&lt;i&gt;main&lt;/i&gt;) de la barra lateral (&lt;i&gt;sidebar&lt;/i&gt;). En mi caso es una imagen como &lt;a href="http://www.blogblog.com/thisaway/bg_main_wrapper.gif"&gt;ésta&lt;/a&gt;, que se repite en el eje vertical (y). En caso de dudas, lo mejor es escribir la dirección de cada imagen en el navegador para ver de qué se trata. Así sabemos en qué parte del código debemos reemplazar.&lt;br /&gt;&lt;div class="code"&gt;#header-wrapper {&lt;br /&gt;padding-bottom: 15px;&lt;br /&gt;background: url(http://www.blogblog.com/thisaway/bg_header_bottom.gif) no-repeat left bottom;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;#header {&lt;br /&gt;background: #634320 url(http://www.blogblog.com/thisaway/bg_header.gif) repeat-x left bottom;&lt;br /&gt;}&lt;/div&gt;&lt;br /&gt;Estas son la imágenes que componen la cabecera. Ambas tienen 760px de longitud. Bueno, necesitaremos bajarlas, editarlas para que tengan 900px y buscar un servidor donde alojarlas. Si tenemos Blogger, entonces también tendremos &lt;a href="http://picasaweb.google.com/"&gt;&lt;s&gt;PicasaWeb&lt;/s&gt;&lt;/a&gt;&lt;a href = "#fn2" title="Ir al pie"&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;. Luego reemplazaremos la &lt;b&gt;url&lt;/b&gt; del &lt;i&gt;template&lt;/i&gt; por la que nos ofrezca el servidor. url significa "una ristra de letras" para nuestros propósitos. Lo mismo haremos para la(s) imagen(es) que usamos como separador. Ejemplos:&lt;br /&gt;&lt;br /&gt;Separador: &lt;a href="http://www.blogblog.com/thisaway/bg_main_wrapper.gif"&gt;antes&lt;/a&gt; y &lt;a href="http://img382.imageshack.us/img382/8864/bgmainwrappercc0.gif"&gt;despues&lt;/a&gt;.&lt;br /&gt;Separador(es) de Pinar: antes (&lt;a href="http://www.blogblog.com/rounders/corners_main_bot.gif"&gt;I&lt;/a&gt;, &lt;a href="http://www.blogblog.com/rounders/corners_main_top.gif"&gt;II&lt;/a&gt;, &lt;a href="http://www.blogblog.com/rounders/rails_main.gif"&gt;III&lt;/a&gt;) y después (&lt;a href="http://img515.imageshack.us/img515/2863/cornersmainbotib8.gif"&gt;I&lt;/a&gt;, &lt;a href="http://img255.imageshack.us/img255/1082/cornersmaintopxd2.gif"&gt;II&lt;/a&gt;, &lt;a href="http://img255.imageshack.us/img255/4488/railsmainfb0.gif"&gt;III&lt;/a&gt;).&lt;br /&gt;Nuevo código de mi separador.&lt;br /&gt;&lt;div class="code"&gt;#content-wrapper {&lt;br /&gt;position: relative;&lt;br /&gt;width: 900px;&lt;br /&gt;background: #f7f0e9 url(http://img382.imageshack.us/img382/8864/bgmainwrappercc0.gif) repeat-y left top;&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Y ya hemos acabado. En mi caso, ha sido también necesario cambiar las imágenes del pie del blog (&lt;i&gt;footer&lt;/i&gt;). Dificultad no tiene ninguna, como todo buen tutorial &lt;i&gt;on-line.&lt;/i&gt; De hecho, poner la etiqueta informática a esto da un poco de grima, pero prefiero no inventar más etiquetas hasta tener nuevos posts del tema. Próximo tutorial: "cómo ofrecer la suscripción a etiquetas del blog con divertidos dibujos inclusive".&lt;br /&gt;Tampoco lo he encontrado en Google.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align:center; font-size:110%"&gt;&lt;b style="margin: auto 0;"&gt;ACTUALIZACIÓN&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;No copies y pegues el código de este post en el template de tu blog&lt;/b&gt;, aunque los colores de tu blog coincidan con los de el mío. Antes, preocúpate de subir las imágenes de fondo a tu propio servidor de almacenamiento de imágenes (como &lt;a href="http://imageshack.us/"&gt;ImageShack&lt;/a&gt;). De lo contrario, estarás utilizando MIS imágenes, y el día menos pensado te puedes quedar sin ellas.&lt;br /&gt;&lt;br /&gt;&lt;div class="footnotes" id="fn1"&gt;&lt;br /&gt;&lt;sup&gt;1&lt;/sup&gt; Si no sabes dónde encontrar el &lt;i&gt;template&lt;/i&gt; de tu blog, mejor saltarte todo el post.&lt;br /&gt;&lt;sup&gt;2&lt;/sup&gt; Picasa no es recomendable, puesto que sólo almacena ficheros JPEG. Yo gasto &lt;a href="http://imageshack.us/"&gt;ImageShack&lt;/a&gt;, en el cual no sé si confiar, después de haberme hecho la jugada de impedir postear imágenes en el blog sin razón alguna. Cosa que, por supuesto, llenó de &lt;a href="http://www.imageshack.us/img/banned.png"&gt;ranas&lt;/a&gt; el mismo. Tras enviar un correo solicitando una explicación encuentro que ya está todo de nuevo arreglado. Por si acaso, hay otros servidores de alojamiento como &lt;a href="http://www.hotlinkfiles.com/"&gt;Hotlinkfiles&lt;/a&gt; y &lt;a href="http://www.filenanny.com/"&gt;Filenanny.&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1150691805752037383-4562420725488958932?l=civada.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://civada.blogspot.com/feeds/4562420725488958932/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1150691805752037383&amp;postID=4562420725488958932" title="8 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/4562420725488958932" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1150691805752037383/posts/default/4562420725488958932" /><link rel="alternate" type="text/html" href="http://civada.blogspot.com/2007/08/1er-bobo-tutorial-ensanchecer-blogger.html" title="1er bobo-tutorial: ensanchecer Blogger" /><author><name>Delirium</name><uri>http://www.blogger.com/profile/08408043740617685786</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>8</thr:total></entry></feed>

