miércoles, 27 de noviembre de 2013

12 de julio de 2011, 01:42

La máquina Enigma, el sistema de cifrado que puso en jaque a Europa

Enigma
La criptografía, palabra que procede del griepo krypto (oculto) y graphos (escritura), es la disciplina científica que se encarga del cifrado y descifrado de mensajes, es decir, enmascarar mensajes mediante un algoritmo de ofuscación que, además, debe permitir devolver el mensaje a su estado original. La criptografía, históricamente, ha estado vinculada a las campañas militares y los secretos de los gobiernos, de hecho, se dice que la primera técnica criptográfica se usó en el siglo V a.C en la antigua Grecia e incluso, posteriormente, por Julio César en sus campañas militares. Pero si hay un período donde la criptografía tomó una vital importancia fue en la Segunda Guerra Mundial, en la que el cifrado y el descifrado de códigos se convirtió en otro frente más de lucha.
Hubo un sistema de cifrado que fue usado por Alemania y que tuvo en jaque a los aliados, sobre todo, en el Atlántico Norte, donde los convoys de material procedente de Estados Unidos caían presa de los submarinos alemanes que se comunicaban entre sí utilizando el código que generaba uno de los inventos más fascinantes de esa época, la máquina Enigma.
La máquina Enigma fue inventada por un ingeniero alemán, Arthur Scherbius, un experto en electromecánica que, tras la Primera Guerra Mundial, quiso aplicar la tecnología existente para mejorar los sistemas de criptografía de los ejércitos. Su idea, patentada en febrero de 1918, consistía en aplicar el Cifrado de Vigenère o, dicho de otra forma, se aplicaba un algoritmo de sustitución de unas letras por otras. Como Scherbius no contaba con recursos para fabricarla, se asoció con Willie Korn que tenía una compañía llamada Enigma Chiffiermaschinen AG en Berlín. Ambos mejoraron el diseño y en 1923 la presentaron en la Exhibición Postal Internacional de Berlín para el cifrado de secretos comerciales.

Scherbius-1928-patent
¿En qué consistía la máquina Enigma? La máquina Enigma era un dispositivo electromecánico, es decir, tenía una parte eléctrica y otra mecánica. El mecanismo consistía en una serie de teclas, con las letras del alfabeto, al igual que una máquina de escribir, que en realidad eran interruptores que accionaban los dispositivos eléctricos y hacían mover unos cilindros rotatorios. El funcionamiento, cara al usuario, era bastante sencillo. El operador tenía que teclear las letras de su mensaje y anotar las letras que devolvía la máquina (a través de un alfabeto que se iba iluminando). El código a usar se fijaba con las posiciones de los cilindros que constaban, cada uno, de 26 cables que se conectaban al teclado pero, con la particularidad, que el primer cilindro giraba un veintiseisavo de vuelta después de cada pulsación, de tal manera que la posición de las conexiones iba cambiando con cada entrada del teclado, obteniendo un cifrado polialfabético. Además, para dar mayor robustez, el segundo cilindro sólo daba un giro cuando el primero había completado 26 giros y el tercero cuando el segundo había dado sus correspondientes 26 y añadió la posibilidad de que los rodillos pudiesen ser intercambiados de posición, de manera que el número de posibilidades aumentase hasta tener 105.456 alfabetos.
Además, el sistema contaba con 6 cables de conexión que también permitían introducir modificaciones dado que podrían conectarse a 26 lugares (representando a las 16 letras del alfabeto de Enigma) lo que producía 100.391.791.500 maneras distintas de conectar los cables que unidos a los 105.456 alfabetos arrojaba 3.283.883.513.796.974.198.700.882.069.882.752.878.379.955.261.095.623.
685.444.055.315.226.006.433.616.627.409.666.933.182.371.154.802.769.920.000.000.000 posibilidades distintas de codificación.
En 1933, Alemania nacionalizó la compañía Enigma Chiffiermaschinen AG y pasó a equipar a todo el ejército Alemán que utilizó estas máquinas de cifrado, a las que le añadieron un cuarto cilindro para complicar aún descifrar de los mensajes. Uno de los primeros casos conocidos de uso de Enigma fue durante la Guerra Civil Española donde fueron utilizadas por el Ejército Español, que contaba con el apoyo de la Alemania nazi.
Durante la Segunda Guerra Mundial, Alemania contaba con una enorme ventaja porque el código de Enigma era, prácticamente, indescifrable; además, el ejército alemán cambiaba cada día el código a usar, de tal forma que los Aliados contaban con un único día para descifrarlo porque, al otro día, se volvía a cambiar (algo que enviaban codificando la clave del día siguiente durante la transmisión codificada del día). El cifrado de comunicaciones alemanas mantuvo en jaque a los aliados durante gran parte de la Guerra puesto que, en todos los frentes, se usaba Enigma para codificar las comunicaciones y, además, cada ejército usaba códigos distintos.
¿Y cómo se logró vencer a Enigma? La máquina fue vencida gracias a varios factores:


  • Estas databan de 1923 y eran modelos comerciales que se distribuyeron por todo el mundo. Si bien es cierto que las máquinas se fueron complicando en sus versiones militares, el principio de funcionamiento ya era conocido.
  • La codificación de un mensaje en Enigma obligaba a los operadores a introducir 3 letras, dos veces, al iniciar el mensaje, una especie de bandera. La Luftwaffe no modificaba esta secuencia y, por tanto, era un patrón que siempre se repetía y que fue aprovechado por Marian Rejewski que fue capaz de descifrar el código gracias a unas máquinas electromecánicas denominadas bombas criptológicas que eran unas máquinas Enigma de procesamiento en paralelo y que buscaban las codificaciones posibles. Los criptógrafos polacos trabajaron junto a los británicos en Bletchley Park para descifrar los códigos alemanes (en este equipo se encontraba Alan Turing).
  • El 9 de mayo de 1941 la Royal Navy capturó el submarino alemán U-110 (a cuya tripulación del fallaron las cargas explosivas para hundirlo) y pudo hacerse con una máquina Enigma y con el preciado libro de claves. Esta captura se mantuvo en secreto y se hizo creer a la opinión pública que el submarino había sido hundido, para que las claves no fuesen cambiadas.
La suma de estos factores obtuvo como resultado el descifrado de los mensajes de Enigma y, por tanto, la drástica disminución de las pérdidas Aliadas en el Atlántico Norte. Ante las sucesivas derrotas, los Alemanes evolucionaron Enigma y crearon una nueva máquina, la M4 pero fue vencida gracias a Colossus, un computador diseñado para descifrar los códigos alemanes.
La historia de Enigma es fascinante así como su funcionamiento (que podéis probar en este simulador). Creo que es una maravilla tecnológica y, en el fondo, de un funcionamiento extremadamente avanzado para la época en la que se diseñó. Tanto es así que gracias a la criptografía durante la Segunda Guerra Mundial nacieron los primeros computadores que, precisamente, se destinaron a descifrar códigos.

Hoy en día Enigma sigue siendo un objeto de estudio y uno de los elementos que más expectación genera en cualquier exposición sobre la Segunda Guerra Mundial.

lunes, 25 de noviembre de 2013

Introducción a phpMyAdmin (parte 0 o resumen)

1 Relacionar Tablas en MySql

Configuraciones Basicas De Windows XP

Como saber que puertos esta usando mi computadora y como desocuparlos en...

Permitir programas por firewall y configurar puertos del router

Programación Java

programacion Java 

Java ArrayList. Estructura dinámica de datos

DECLARACIÓN Y CREACIÓN DE UN ARRAYLIST
De forma general un ArrayList en Java se crea de la siguiente forma:
ArrayList nombreArray = new ArrayList();
Esta instrucción crea el ArrayList nombreArray vacío.
Un arrayList declarado así puede contener objetos de cualquier tipo.
Por ejemplo:
ArrayList a = new ArrayList();
a.add("Lenguaje");
a.add(3);
a.add('a');
a.add(23.5);
Los elementos del arrayList a son:
  “Lenguaje”  2  ‘a’   23.5
Es decir, un ArrayList puede contener objetos de tipos distintos.
En este ejemplo, el primer objeto que se añade es el String “Lenguaje”. El resto no son objetos. Son datos de tipos básicos pero el compilador los convierte automáticamente en objetos de su clase envolvente (clase contenedora o wrapper) antes de añadirlos al array.
Un array al que se le pueden asignar elementos de distinto puede tener alguna complicación a la hora de trabajar con él. Por eso, una alternativa a esta declaración es indicar el tipo de objetos que contiene. En este caso, el array solo podrá contener objetos de ese tipo.
De forma general:
ArrayList<tipo> nombreArray = new ArrayList<tipo>();
tipo debe ser una clase. Indica el tipo de objetos que contendrá el array.
No se pueden usar tipos primitivos. Para un tipo primitivo se debe utilizar su clase envolvente.
Por ejemplo:
ArrayList<Integer> numeros = new ArrayList<Integer>();
Crea el array numeros de enteros.
MÉTODOS DE ARRAYLIST
Algunos métodos que proporciona ArrayList son:
MÉTODO
DESCRIPCIÓN
size()
Devuelve el número de elementos (int)
add(X)
Añade el objeto X al final. Devuelve true.
add(posición, X)
Inserta el objeto X en la posición indicada.
get(posicion)
Devuelve el elemento que está en la posición indicada.
remove(posicion)
Elimina el elemento que se encuentra en la posición indicada. Devuelve el elemento eliminado.
remove(X)
Elimina la primera ocurrencia del objeto X. Devuelve true si el elemento está en la lista.
clear()
Elimina todos los elementos.
set(posición, X)
Sustituye el elemento que se encuentra en la posición indicada por el objeto X. Devuelve el elemento sustituido.
contains(X)
Comprueba si la colección contiene al objeto X. Devuelve true o false.
indexOf(X)
Devuelve la posición del objeto X. Si no existe devuelve -1
Los puedes consultar todos en:
RECORRER UN ARRAYLIST
Podemos recorrerlo de forma clásica con un bucle for:
for(int i = 0;i<array.size();i++){
            System.out.println(array.get(i));
}
Con un bucle foreach:
Si suponemos el array de enteros llamado numeros:
for(Integer i: numeros){
           System.out.println(i);
}
Si el array contiene objetos de tipos distintos o desconocemos el tipo:
for(Object o: nombreArray){
            System.out.println(o);
}
Utilizando un objeto Iterator.
La ventaja de utilizar un Iterador es que no necesitamos indicar el tipo de objetos que contiene el array.
Iterator tiene como métodos:
hasNext: devuelve true si hay más elementos en el array.
next: devuelve el siguiente objeto contenido en el array.
Ejemplo:
ArrayList<Integer> numeros = new ArrayList<Integer>();
…..
//se insertan elementos
.....
Iterator it = numeros.iterator(); //se crea el iterador it para el array numeros
while(it.hasNext())                    //mientras queden elementos
        System.out.println(it.next());  //se obtienen y se muestran
EJEMPLOS DE USO DE ARRAYLIST
Ejemplo 1:
ArrayList<String> nombres = new ArrayList<String>();
nombres.add("Ana");
nombres.add("Luisa");
nombres.add("Felipe");
System.out.println(nombres); // [Ana, Luisa, Felipe]
nombres.add(1, "Pablo");
System.out.println(nombres); // [Ana, Pablo, Luisa, Felipe]
nombres.remove(0);
System.out.println(nombres); // [Pablo, Luisa, Felipe]
nombres.set(0,"Alfonso");
System.out.println(nombres); // [Alfonso, Luisa, Felipe]
String s = nombres.get(1);
String ultimo = nombres.get(nombres.size() - 1);
System.out.println(s + " " + ultimo);  // Luisa Felipe
Ejemplo 2: Escribe un programa que lea números enteros y los guarde en un ArrayList hasta que se lea un 0 y muestra los números leídos, su suma y su media.
import java.util.*;
public class ArrayList2 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        ArrayList<Integer> numeros = new ArrayList<Integer>();
        int n;
        do {
            System.out.println("Introduce números enteros. 0 para acabar: ");
            System.out.println("Numero: ");
            n = sc.nextInt();
            if (n != 0)
                numeros.add(n);
        }while (n != 0);
       
        System.out.println("Ha introducido: " + numeros.size() + " números:");
       
        //mostrar el arrayList completo
        System.out.println(numeros);
       
        //recorrido usando un iterador para mostrar un elemento por línea
        Iterator it = numeros.iterator();
        while(it.hasNext())
              System.out.println(it.next());
        
        //recorrido usando foreach para sumar los elementos
        double suma = 0;
        for(Integer i: numeros){
            suma = suma + i;
        }
        System.out.println("Suma: " + suma);
        System.out.println("Media: " + suma/numeros.size());
    }
}
COPIAR UN ARRAYLIST
El nombre de un ArrayList contiene la referencia al ArrayList, es decir, la dirección de memoria donde se encuentra el ArrayList, igual que sucede con los arrays estáticos.
Si disponemos de un ArrayList de enteros llamado ventas:







La instrucción:
ArrayList<Integer> ventas1 = ventas;
No copia el array ventas en el nuevo array ventas1 sino que crea un alias:







De esta forma tenemos dos formas de acceder al mismo ArrayList: mediante la referencia ventas y mediante la referencia ventas1.
Para hacer una copia podemos hacerlo de forma manual elemento a elemento o se puede pasar la referencia del ArrayList original al constructor del nuevo:
ArrayList<Integer> ventas1 = new ArrayList<Integer>(ventas);
ARRAYLIST COMO PARÁMETRO DE UN MÉTODO
Un ArrayList puede ser usado como parámetro de un método. Además un método puede devolver un ArrayList mediante la sentencia return.
Ejemplo: Método que recibe un ArrayList de String y lo modifica invirtiendo su contenido:
import java.util.*;
public class ArrayList4 {
    public static void main(String[] args) {
        ArrayList<String> nombres = new ArrayList<String>();
        nombres.add("Ana");
        nombres.add("Luisa");
        nombres.add("Felipe");
        nombres.add("Pablo");
        System.out.println(nombres);
        nombres = invertir(nombres);
        System.out.println(nombres);
    }
    public static ArrayList<String> invertir(ArrayList<String> nombres) {
        // Crea una lista para el resultado del método
        ArrayList<String> resultado = new ArrayList<String>();
        // Recorre la lista de nombres en orden inverso
        for (int i = nombres.size() - 1; i >= 0; i--) {
             // Añade cada nombre al resultado
              resultado.add(nombres.get(i));
        }
        return resultado;
    }
}
ARRAYS BIDIMENSIONALES UTILIZANDO ARRAYLIST
Un ArrayList es un array unidimensional, pero con ellos podemos simular arrays de dos o más dimensiones anidando ArrayLists.
Para crear una matriz lo que creamos es un ArrayList cuyos elementos son a su vez ArrayList. Esto se puede extender sucesivamente y obtener arrays de más dimensiones.
Ejemplo:
Programa que lee las notas de 10 alumnos y las guarda en un ArrayList Bidimensional. Cada alumno tiene un número indeterminado de notas. La lectura de notas de cada alumno acaba cuando se introduce un número negativo. Finalmente se muestran todas las notas de todos los alumnos.

public static void main(String args[]){
        Scanner sc = new Scanner(System.in);
        final int numAlumnos = 10;  //número de alumnos
        int i, j, nota, cont = 1;
       
        //crear un ArrayList bidimensional de enteros vacío
        //Realmente se crea un ArrayList de ArrayLists de enteros
        ArrayList<ArrayList<Integer>> array = new ArrayList<ArrayList<Integer>>();
       
        //Se leen las notas de cada alumno.
        System.out.println("Introduzca notas. <0 para acabar");
        for(i=0;i<numAlumnos;i++){
            cont = 1;
            System.out.println("Alumno " + (i+1) + ": ");
            System.out.print("Nota " + cont + ": ");
            nota = sc.nextInt();
           //para cada alumno se añade una nueva fila vacía
           //esto es necesario porque el arrayList se crea vacío
            array.add(new ArrayList<Integer>());
            while(nota>=0){
                array.get(i).add(nota); //en la fila i se añade un nueva nota
                cont++;
                System.out.print("Nota " + cont + ": ");
                nota = sc.nextInt();             
            }           
        }
       
        //Mostrar todas las notas
        System.out.println("Notas de alumnos");
        for(i=0;i<array.size();i++){  //para cada alumno (para cada fila)
            System.out.print("Alumno " + i + ": ");
            for(j=0;j<array.get(i).size();j++){  //se recorre todas la columnas de la fila
                System.out.print(array.get(i).get(j) + " "); //se obtiene el elemento i,j
            }
            System.out.println();          
        }
    }

 

Java Recorrer Colecciones [ Collection ] usando for/while Parte 1

 

JAVA RECORRES COLECCIONES USUANDO FOR WHILE 

La clase ArrayList (java.util)

ARRAY LIST

Aplicacion Java y MySQL, Netbeans - Parte3



Aplicacion Java y MySQL, Netbeans - Parte3