Sustituir los saltos de línea Win por saltos Linux

¿Son todos los saltos de línea iguales?  No señor !  Hay saltos y saltos 🙂  Por ejemplo, los siguientes son saltos típicos de un editor de textos Windows:

Los ^M que aparecen en la imagen son realmente la representación visual de «rn» (carriage return + line feed), es decir, el salto de línea típico de Windows. Un fichero en PHP con esos saltos de línea se pueden ejecutar sin problemas en Linux. Pero cuando los editamos con el Vim (o $EDITOR de confianza), la verdad es que los ^M dan grima. Esto ocurre porque en Linux el salto de línea se representa como n , a secas (sin el r ).  Podemos convertir un fichero con saltos Win a otro con saltos Linux con el comando sed:

sed 's/^M$//' fichero

O bien, si no nos acordamos del conjuro, seguro que nos viene a la memoria el mnemotécnico «fromdos» (de MSDOS a Unix):

  fromdos fichero

que automágicamente detecta y convierte (de MSDOS a Unix o viceversa) el fichero pasado como parámetro. fromdos es un comando del paquete tofrodos.

El acertijo de Einstein

Hey_Neken nos quiso volver locos con el level3 del HackIt!2010. Para ello nos pasó como enunciado el conocido como «acertijo de Einstein»:

Tenemos las siguientes claves:

  • El británico vive en la casa roja.
  • El sueco tiene un perro.
  • El danés toma té.
  • La casa verde esta a la izquierda de la blanca.
  • El dueño de la casa verde toma café.
  • La persona que fuma Pall Mall tiene un pájaro.
  • El dueño de la casa amarilla fuma Dunhill.
  • El que vive en la casa del centro toma leche.
  • El noruego vive en la primera casa.
  • La persona que fuma Brends vive junto a la que tiene un gato.
  • La persona que tiene un caballo vive junto a la que fuma Dunhill.
  • El que fuma Bluemasters bebe cerveza.
  • El alemán fuma prince.
  • El noruego vive junto a la casa azul.
  • El que fuma Brends tiene un vecino que toma agua.

Y por ultimo la pregunta:
¿Quién es el dueño del pececito?

Bien, el acertijo tiene solución, y la podéis encontrar detallada aquí. El problema es que esa no era la solución al level3…   Una pista: analizad todo lo que nos envía el servidor…

Movimientos relativos a Soft Libre en el Gobierno Vasco

Álex Etxeberría (parlamentario del PNV) solicitó los estudios pendientes de la Oficina Técnica del Software Libre (a propósito entre otras cosas del estudio de implantación de OpenOffice en el GV). El 1 de Marzo parece ser que el señor Etxeberría recibió la respuesta a dicha petición, en un CD que incluía todo lo solicitado. Digo parece porque no está accesible en la web del Parlamento :-
Desconozco si es posible acceder a esa información, pero para comprobarlo, he solicitado hoy mismo por email una copia de dicha documentación al señor Etxeberría.

El 4 de Marzo, el mismo parlamentario envió una nueva remesa de preguntas a la Consejera de Justicia y Administraciones Públicas (Idoía Mendía, PSE):

(Nota del Editor: sabiendo que el contrato de la Oficina Técnica del Software Libre supuestamente expiró el 31 de Diciembre de 2010…)

* ¿qué intenciones tiene el departamento de cara al futuro entorno a la oficina técnica de sotware libre? ¿Qué funciones va a realizar en el futuro esa oficina? ¿Cómo va a realizar esos trabajos?

* El contrato realizado con la empresa Agoranel 2000, SL (Nota del Editor: a quien se adjudicó la Oficina del Soft Libre) estpulaba que los trabajos debían realizarse en las dos lenguas. Sin embargo, los enviados a este parlamentario solo están en casfellano. ¿Por qué? Tiene intención el departamento de traducir al euskera dichos trabajos?

Para terminar una nota curiosa: Izenpe ha publicado hoy a través del BOPV un ANUNCIO de licitación del contrato que tiene por objeto los servicios «Servicios de soporte bajo Windows GNU/Linux y Mac OS» (Expediente: IZNP-S_008-2011). Leyendo el PDF más en detalle vemos lo siguiente:

«el objeto del presente pliego es la contratación por parte de Izenpe, S.A. de los servicios para la realización de guías de instalación y configuración para el correcto uso de los certificados de Izenpe en sistemas operativos Linux, Mac y Windows, instalables ligeros, guías para solicitar e instalar certificados de servidor SSL, generación de notas técnicas, soporte de 2.º nivel específico para plataformas Windows, GNU/Linux y Mac OS X, testeo de los productos de Izenpe sobre sistemas operativos Windows, Linux y Mac.»

Es una buena noticia, espero seguir leyendo cosas como éstas en el futuro.

HackIt’2010: Level 2

Más de lo mismo 🙂 Aunque ahora el código Javascript está ofuscado con un empaquetador (packer).
Basta con abrir el level2.js y analizar la primera línea:

eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\b'+e(c)+'\b','g'),k[c]);return p}('C D(){f a=q.t('u').w;f r=z A(8);f x="";B(f i=0;i<r.g;i++){r[i]=z A()}c(a.g==8){c(a.b(5)=="n"){r[7]=["l","j","k","j","9","1","l","m"];c(a.b(4)=="0"){r[2]=["x","d","e","j"];c(a.b(0)=="3"){r[8]=["s","s","3","j","o","E","k"];c(a.b(3)=="y"){r[6]=["7","5","k","j","n","v","k"];r[0]=["l","j","k","j"];c(a.b(1)=="4"){r[3]=["l","j","4","j"];r[1]=["l","j","k","j"];c(a.b(2)=="s"){r[5]=["l","j","k","j","h","o","p"];c(a.b(6)=="3"){r[4]=["l","j","k","j","2","8","h"];B(f j=0;j<r[7].g;j++){x=x+r[j][j]}c(x.F("e","3")==r[7][0]+r[2][3]+a.b(6)+r[5][3]+"2"+r[8][4]+r[1][2]+r[7][7]){q.t('u').w=a.b(0)+a.b(1)+a.b(2)+a.b(3)+a.b(4)+a.b(5)+a.b(6);G()}}}}}}}}}}',43,43,'|||||||||||charAt|if|||var|length||||||||||document|||getElementById|password||value|||new|Array|for|function|check|S|replace|Login'.split('|'),0,{}))

Busando packers de Javascript en Google, llegamos a éste (usando «eval(function(p,a,c,k,e,r)» como cadena de búsqueda).

Desempaquetamos y obtenemos código mucho más clarito (donde vemos también que hey_neken metió líneas de código espurio)

function check() {
	var a = document.getElementById('password').value;
	var r = new Array(8);
	var x = "";
	for (var i = 0; i < r.length; i++) {
		r[i] = new Array()
	}
	if (a.length == 8) {
		if (a.charAt(5) == "n") {
			r[7] = ["l", "j", "k", "j", "9", "1", "l", "m"];
			if (a.charAt(4) == "0") {
				r[2] = ["x", "d", "e", "j"];
				if (a.charAt(0) == "3") {
					r[8] = ["s", "s", "3", "j", "o", "S", "k"];
					if (a.charAt(3) == "y") {
						r[6] = ["7", "5", "k", "j", "n", "v", "k"];
						r[0] = ["l", "j", "k", "j"];
						if (a.charAt(1) == "4") {
							r[3] = ["l", "j", "4", "j"];
							r[1] = ["l", "j", "k", "j"];
							if (a.charAt(2) == "s") {
								r[5] = ["l", "j", "k", "j", "h", "o", "p"];
								if (a.charAt(6) == "3") {
									r[4] = ["l", "j", "k", "j", "2", "8", "h"];
									for (var j = 0; j < r[7].length; j++) {
										x = x + r[j][j]
									}
									if (x.replace("e", "3") == r[7][0] + r[2][3] + a.charAt(6) + r[5][3] + "2" + r[8][4] + r[1][2] + r[7][7]) {
										document.getElementById('password').value = a.charAt(0) + a.charAt(1) + a.charAt(2) + a.charAt(3) + a.charAt(4) + a.charAt(5) + a.charAt(6);
										Login()
									}
								}
							}
						}
					}
				}
			}
		}
	}
}

Siguiendo las comprobaciones de las ramas if, llegamos a:

     0 1 2 3 4 5 6 7
     3 4 s y 0 n e .

Donde la longitud ha de ser de 8 caracteres, siendo el último de ellos uno cualquiera. Y con esto, llegamos al level3 donde estuvimos un buen rato atascados… a ver qué tal se os da a vosotros 😉

HackIt 2010: Solución al level 1

SPOILER! Si quieres resolverlo por tu cuenta, no sigas leyendo (Edit: recuerda que el HackIt! 2010 está disponible en la web de Marcan)

Tú lo has querido, estabas avisado…

Analizando el código fuente veremos la siguiente función Javascript (que he desplegado para que el código se vea mejor):

 
function check(){
...
    if(pass.charCodeAt(0) == "102"){
        if(pass.charCodeAt(1) == "52"){
             if(pass.charCodeAt(6) == "115"){
                  if(pass.charCodeAt(3) == "49"){
                      if(pass.charCodeAt(8) == "109"){
                         if(pass.charCodeAt(5) == "49"){
                               pass2 = pass.replace("i","1").replace("a","4").replace("o","0");
                               if(pass.charCodeAt(2) == "99"){
                                     if(pass.charCodeAt(7) == "49"){
                                         if(pass.charCodeAt(4) == "108"){
                                              if(pass.charCodeAt(9) == "111"){
                                                       Login();

Es decir, se comprueba letra a letra la cadena que hayas metido como password. Para que no sea trivial, en lugar de comprobar el carácter en sí, se comprueba su código ASCII. Y en una línea especial se busca que todas las i se sustituyan por el número 1, las a por el 4 y las o por el número 0 (esta última sustitución es una pequeña trampa, porque en la última rama del if se comprueba que la última letra sea realmente una o – y no un 0 – )

Así pues:

Posición: 0    1    2    3     4    5    6     7       8     9
ASCII    102   52   99   49   108   49   115  49     109   111
carácter  f    4   c    1     l     1    s    1      m     o

El autor del level (hey_neken) lo decía en el propio enunciado, el password es f4c1l1s1mo .