Buscando un buen editor de textos para programar

Yo era de los que usaba medit; pero antes de medit fue kate. Siempre pasa igual, lo empiezas a usar y bien, pero con el tiempo, con las actualizaciones, ya no es lo mismo. Aparecen unas pegas u otras y al final te cansas. Dejé kate porque me resultaba demasiado pesado, y la gestión del encoding que tenía era (para mí) muy pobre.

Pasé a medit entonces, muy contento porque era más ligero, más sencillo, y la autodetección del encoding era una maravilla. Hasta hace poco.

Cuando actualicé a Gnome3, una de las cosas que se estropeó fue el medit. Y eso es de lo peor que me podía pasar. Sin un buen editor de textos me siento un poco manco. Primero detecté que los atajos de teclado no funcionaban, Ctrl+s, Ctrl+f y demás no funcionaban. Lo conseguí arreglar. Pero ahora me doy cuenta de que la autodetección de encoding se ha vuelto loca. No encuentro forma de arreglarlo ni parece que le pase a nadie.

Así que, hoy he decidido buscar todos los editores similares que existan y realizar un análisis a todos ellos a ver qué tal.

Los editores con IDE, descartados, excepto que puedan realizar lo mismo que un editor sencillo en el mismo tiempo, y que el tiempo de arranque sea aproximadamente cero. Eclipse por lo tanto, no es una opción.

Los editores de KDE, descartados por el tiempo de arranque desde fuera de KDE. Actualmente uso Gnome.

Veamos pues…

Conocidos:

  • GEdit. El editor por defecto en Gnome. Siempre le doy muchas más oportunidades que al resto por ser el que viene by-default. Pero sinceramente, es un poco pobre. Está más en el sitio de los Notepads que de los editores de programación. Tiene muchas incomodidades (Teclas rápidas, funcionamiento de la búsqueda, lo que considera qué es una palabra y qué no…) y aparte es muy poco configurable.
  • MEdit. Hasta hace dos días me parecía de los mejores. Es bastante configurable. Pero, a veces no hace ni puñetero caso de la configuración o no la guarda bien. Ahora lo que pasa es que de la autodetección de encoding, ni olerla. Tengo que ir revisando cada vez con qué encoding he abierto. Uf! creo que he vuelto 5 años atrás en el tiempo.

Gráficos, sin IDE:

  • Editra. Aunque al principio aparece un splash que hace presagiar lo peor… (que va a aparecer un pesadísimo IDE), la verdad es que es muy ligero, y el splash se puede quitar. El tiempo de carga es bastante rápido y parece más completo que el medit. La autodetección parece funcionar bastante bien, pero falta una lista de encodings preferidos y una especie de fallback. Cuando falla pregunta, y el listado de posibles es cuasi infinito.
IDE:
  • Geany. Parece que funciona muy bien. Su arranque está por debajo de las 2 décimas de segundo. Tiene gestión de sesiones, reconoce y lista símbolos del programa, autodetecta bien el encoding… Parece muy bueno.

Para consola:
Yo pensaba que en la consola o era vim, o emacs. Y cuando descubrí nano, dije, anda, esto mola. Es más sencillo. Pero no, hay muchos más y me recuerdan al Turbo C++ y el Turbo Pascal. Está bastante ingenioso… Los iré probando con calma, no creo que alcancen la flexibilidad y rapidez de un editor GUI, pero la verdad, se ven muy prácticos para cuando accedo por SSH a una máquina a modificar código directamente. Lo malo de esto, es que parece que la gestión de la codificación la realiza la terminal, así que depende íntegramente de con qué encoding tiene tu terminal en concreto.

  • FTE. (sfte) Un editor al estilo Turbo C++. Si no especificas fichero te abre un selector de carpetas al estilo Norton Commander. Los accesos por teclas se parecen a los del Turbo C.
  • jed. Otro editor, pero este parece un poco más a… ¿emacs tal vez?. Lo de las teclas rápidas que tiene se me escapa mucho y me pierdo. No está nada mal, pero no lo termino de entender.
  • dav, otro editor, más sencillo aún, sin coloreo de código. Creo que no vale la pena.
  • xwpe. Este sí es un calco del Turbo C++. Pero tiene menos soporte para colorear sintaxis y las opciones son más complejas de encontrar y poner.
  • ne. Similar a nano.
  • jupp. Similar a ne y nano.

Conclusión:

Tengo que probar Geany, como editor principal con IDE. Editra también parece buena opción.

Y sin duda, tengo que probar FTE a través de consola, a ver si es tan bueno como parece.

Cómo licenciar tu proyecto de software libre

Escribes un software y te dices: ¡voy a liberarlo! ¡que sea software libre!

Sí, pero, ¿qué licencia le vas a poner? ¿crees que no importa? la licencia es uno de los mayores problemas a la hora de unir piezas del software libre. Llevo ya tiempo viendo un mal uso de las licencias en los programas, generalmente por desconocimiento, pero tampoco falta la mala fe en algunos casos. Así que, voy a explicar qué licencia deberías poner según el tipo de software que estés escribiendo y cómo licenciarlo.

Lo primero de todo es no inventarse licencias o textos legales. Es una regla de oro. Los temas legales son delicados y deben llevarlo la gente que tiene conocimientos sobre derecho. De lo contrario tu licencia puede que tenga efectos inesperados, y es mejor no jugar con estas cosas. La verdad, no he visto nunca una licencia inventada, pero nunca está de más decirlo.

Entre las licencias a elegir uno de los factores más importantes a tener en cuenta es si tienen copyleft o no. Copyleft es el requisito que agregan algunas licencias para impedir que otra persona coja un trabajo y lo redistribuya con posibles modificaciones bajo otros términos. El gran problema del copyleft es que causa muchos conflictos entre licencias, que incluso pueden ser muy similares entre sí. El problema de una aplicación con licencia que no tiene copyleft es que un tercero puede acabar haciendo una versión alternativa privativa y incluso sacar provecho económico sin que se pueda hacer nada. Así que es una cuestión bastante delicada.

Según cómo creemos que nuestro software será usado por otros programadores escogeremos unas licencias u otras. Por ejemplo, si nuestro software está pensado para ser incrustado (es decir, para hacer un “include” desde C o para que modifiquen los propios ficheros), entonces diría que es necesario que la licencia no lleve copyleft (BSD/MIT). Si lo lleva, estaremos obligando a todo el mundo que incruste nuestra librería a que use nuestra licencia. Y aunque en principio esto parece que es “bueno”, a la larga es fatal, porque todos los autores tienden a hacer lo mismo y no puedes poner 5 licencias a la vez, sólo puede haber una para todo el global.

Si el software es una librería y está pensada para ser cargada como módulo dinámico o como compilado como objeto, entonces podemos poner un copyleft débil (MPL/LGPL), que proteja la librería, pero que no contamine a la aplicación que quiera enlazarla. Y por supuesto, si la librería incluye ejemplos y/o cabeceras (headers), habría que licenciar esas partes explícitamente con una licencia sin Copyleft, porque estrictamente hablando, incluir un header LGPL hace que tu aplicación sea LGPL.

Si por último tu software no está pensado para ser usado como una librería de una aplicación más grande, es decir, que es una aplicación en sí misma y carece de sentido pensar en ella como librería, entonces se puede poner una licencia con copyleft fuerte o vírico (GPL) que garantizaría con la mayor seguridad posible que nadie la use con otros términos. Si tu aplicación tiene algún apartado específico para cargar librerías de terceros (plugins, etc) o dispone de una librería para interoperar con la aplicación, seguramente deberías licenciar aparte esos casos. De otro modo provocarías que todo los plugins escritos para tu programa, o todo programa enlazando con la librería tuvieran que tener la misma licencia.

Un caso especial que me queda es el de la Affero GPL. Pero en mi opinión personal esta licencia sobrepasa el límite de copyleft y presenta muchos problemas a la hora de desarrollar sobre una aplicación que directa o indirectamente está sobre la AGPL, así que suelo intentar evitarla. Más adelante haré un artículo sobre mi opinión de esta licencia.

Cada licencia suele tener instrucciones de cómo licenciar. Es importante leérselas y aplicarlas lo mejor posible. Si la licencia tiene la opción de incluir el texto “or at your option, any later version” como es el caso de la LGPL, GPL y MPL; por favor, no lo quites. Si no te gusta que le puedan hacer un upgrade a la licencia porque es como “firmar un cheque en blanco”, creo que lo más recomendable es buscar licencias sin Copyleft. Las licencias con copyleft son problemáticas y necesitan de esa cláusula para poder solucionar los problemas legales en el futuro. Ya me ha pasado varias veces al mezclar código que no deja hacer upgrade y provoca conflictos incluso dentro de distintas versiones de la misma licencia donde los términos son en espíritu los mismos.

Poner el fichero “LICENSE” en la raíz del proyecto es recomendable pero no es suficiente. Debe existir otro fichero (por ejemplo “COPYING”) donde se diga específicamente que este software XYZ se distribuye bajo los términos de la licencia ABC; o también es buena idea incluir esto al inicio de cada fichero. Las licencias incluyen al final una plantilla para estos textos.

Fragmentación de ficheros en Linux

Cuando empezamos con Linux, al cabo del tiempo nos viene a la mente aquello de desfragmentar. Sí, eso que hacíamos en Windows y en MSDOS cada cierto tiempo para evitar que el ordenador se vuelva terriblemente lento. Pero cuando intentamos desfragmentar no encontramos la forma en Linux. Preguntamos y dicen: “En linux no hace falta desfragmentar”, o peor aún, “Linux no sufre del problema de la fragmentación de ficheros”.

Pues no, es falso. Lo siento mucho. La fragmentación es un problema inherente a cualquier sistema de ficheros, a cualquier unidad de disco. Así que en Linux como en cualquier otro sistema operativo los ficheros se fragmentan y puede ralentizar bastante el trabajo de los discos. ¿Porqué dicen que no hace falta desfragmentar entonces? Es bastante sencillo, porque en condiciones normales, los sistemas de ficheros modernos (no sólo los de linux) consiguen mantener la fragmentación a un mínimo. Que no ocurra, y si ocurre minimizarla. Incluso es posible que alguno de éstos aproveche una escritura para reorganizar bloques próximos.

Antiguamente, con FAT32, este problema no estaba nada resuelto; y es cierto que había que desfragmentar de tanto en tanto. Pero por ejemplo para NTFS ya no es necesario. Lo mismo ocurre con XFS, EXT3 y otros. Mientras el uso del disco sea inferior a un 30%, es prácticamente imposible que exista una fragmentación apreciable. A partir de un 60% de uso es cuando empiezan a tenerlo un poco más complicado, y conforme nos acercamos al 100% de uso la dificultad para no fragmentar aumenta exponencialmente.

Si queremos desfragmentar una partición, pasa un poco lo mismo. Más difícil cuanto más lleno. Así que, la recomendación ahora ya no es desfragmentar cada cierto tiempo, sino mantener siempre algo de espacio libre en el disco. Por ejemplo un uso del 60% de disco nos da espacio suficiente para que no haya casi fragmentación en un servidor, y pueda estar funcionando sin requerir mantenimiento.

¿Y para qué desfragmentar hoy en día? Creo que está bastante claro, cuando realizamos un mantenimiento ocasional a un equipo y hacemos una limpieza previa de ficheros, es bueno desfragmentar la unidad si originalmente estaba muy llena. Así empieza a rodar bien otra vez.

En mi caso me pasó que notaba el disco duro muy lento. Lo llevaba agonizando durante un año; no sé muy bien porqué, lo achaco a algún defecto en el disco. El caso es que estaba leyendo una entrada de la wikipedia sobre tamaños de bloques en particiones EXT3 y XFS; y sorpresa, leo sobre un comando xfs_fsr para defragmentar mi sistema de ficheros “on-line”, sin tener que desmontar la partición.

Me puse manos a la obra. Borré todo lo que ya no necesitaba y liberé todo el espacio posible. Luego revisé el manual de xfs_fsr y la verdad, el uso del comando es tremendamente simple. Lo ejecutamos como root, sin argumentos y desfragmentará todas nuestras unidades XFS montadas durante 2 horas. Tiene opciones para cambiar esto, pero no son necesarias por lo general. El equipo se puede usar sin problemas mientras tanto.

Después de la desfragmentación puedo decir que se nota. No es que sea muchísimo más rápido, pero va bastante mejor que antes. Se ve que lo tenía bastante fragmentado de lo lleno que estaba.

Intercambio de claves Diffie-Hellman con Python

Llevaba yo un año y pico detrás de este algoritmo, que la verdad es tremendamente sencillo de entender e implementar, pero nunca tuve el tiempo ni la paciencia para sentarme a leerlo bien y entenderlo. Hace menos de una semana conseguí que funcionase perfectamente.

El sistema de intercambio de claves de Diffie-Hellman sirve para lo siguiente: tenemos dos personas, Ana y Belén que quieren realizar una comunicación segura, pero no se conocen entre ellas, o al menos, no tienen una clave común con la que cifrar. Este sistema consigue que las dos lleguen a una misma clave común sin transmitirla por la línea, ni tampoco transmitir nada a través de lo cual podamos computar sencillamente el valor. Esto se usa prácticamente en cualquier sistema de comunicaciones cifradas, así que es bastante didáctico el implementarlo manualmente.

La idea es muy sencilla. Primero Ana y Belén tienen que acordar un número primo y un generador a usar. Pueden ser valores fijos, especialmente el generador, que suele ser 2 o 5 (según wikipedia). El número primo suele ser de unos 512bits en adelante, pero podemos usar para nuestras modestas pruebas el 13. (Hay que tener en cuenta que si el número primo no cambia nunca, podrían existir ataques de fuerza bruta eficientes al estilo rainbow tables contra ese primo). Para el generador escogemos el 2.

Una vez tenemos esto, cada parte tiene que calcular un número privado que llamaremos (a) y (b) respectivamente. Este número tiene que ser un número realmente aleatorio, mayor que cero y inferior al número primo. En este caso sería entre 1 y 13. Pongamos que (a) = 4 y (b) = 7

Luego, cada uno calcula su número público y lo envía al otro extremo: A = g^(a) % p  ; B = g^(b) % p   (g = 2, p = 13)

A = 2 ** 4 % 13 = 3 ; B = 2 ** 7 % 13 = 11

Con esta información Ana y Belén ya pueden calcular lo que se llama el shared secret:

(Ana): S = B ** a % p = 11 ** 4 % 13 = 3

(Belén): S = A ** b % p = 3 ** 7 % 13 = 3

Y las dos han llegado a la misma conclusión, sin transmitirla por la línea. Si aumentamos el tamaño del número primo obtenemos un valor de “S” mucho más grande, casi tan grande como el número primo. Este valor se suele usar como semilla en una clave de cifrado simétrico.

¿Cómo es posible que lleguen al mismo valor? Pues al parecer porque si despejamos de las ecuaciones los valores A y B: [Me tomo una pequeña licencia con el módulo de P]

(Ana): S = B ** a % p = g ** b ** a % p = g ** (b * a) % p

(Belén): S = A ** b % p = g ** a ** b % p = g ** (a * b) % p

Como en definitiva están multiplicando los mismos valores, el resultado es idéntico.

Ahora bien, ¿qué oportunidades tiene un atacante para descubrir el valor de S? Pues al parecer necesita conocer (a) o (b) y para ello tiene que probar valores posibles de (a) hasta encontrar el que coincida con la operación g ** (a) % p = A. Hay algoritmos según leo en la wikipedia, pero el problema es que todos son iterativos y no ahorran mucho tiempo, lo que al final se traduce en ir probando.

La seguridad de esta implementación depende directamente del tamaño del número primo. Tamaños como 64 o 128bits son inseguros y sirven para poco más que para ofuscar los datos débilmente. Depende de qué cantidad de esfuerzo vaya a invertir un atacante en romper una clave, pero en todo caso sólo rompería la clave de una única sesión, teniendo que repetir el proceso en cada conexión o intercambio de llaves.

Cuando digo inseguro, me refiero a que se puede romper, no que sea fácil hacerlo. De hecho no tengo la menor idea de cuanto tiempo tomaría intentar romper una de 64bits. En mi ordenador, con un algoritmo trivial y una clave de 21 bits, se tarda 4 segundos de media en encontrar el valor de (a). Supongamos que la clave es de 32, 48 y 64; Como para 22 bits hacen falta el doble de 21, con algo de matemáticas, parece que necesitaríamos 2 horas, 17 años y 100.000 años respectivamente para cada una de las claves. Hay algoritmos que aceleran esto, no sé cuanto, pero todos los algoritmos tienen que ir probando, así que la relación siempre es que para 22 bits cuesta el doble de que con 21.

Si no queremos que nadie lo pueda romper recomiendan 1024 bits por lo menos. Pero en fin, esto es como todo, si realmente queremos seguridad lo mejor sería usar SSL, que implementa esto y muchas más cosas y es realmente seguro contra prácticamente todo ataque.

Si alguien quiere implementarlo por su cuenta, sólo hay que tener en cuenta dos cosas. Primero, la librería PyCrypto lleva un generador de primos, es imprescindible para esto. Y segundo, hay que usar la función de python “pow(x,y,z)” si queremos que el cómputo termine antes del año que viene.
Un mini ejemplo:
from Crypto.Util.number import getPrime
from random import randint
g = 2; p = getPrime(512)
a = randint(p/4,p-1)
b = randint(p/4,p-1)
A = pow(g,a,p) # g ^ a % p
B = pow(g,b,p) # g ^ b % p
S_A = pow(B,a,p)
S_B = pow(A,b,p)
assert(S_A == S_B)
print g,p
print A
print B

Cómo realizar la comunicación entre las dos partes ya queda a gusto de cada cual. Mi librería bjsonrpc podría venir bien para estas cosas.