Laboratorio de Programación Entrada / Salida (ficheros) Ejercicio e3

Anuncio
Laboratorio de Programación
Entrada / Salida (ficheros)
Ejercicio e3
Dpto. de Ingeniería de Sistemas Telemáticos
http://www.lab.dit.upm.es/~lprg/
Ficheros
Donde se almacenan datos permanentemente
disco duro: C:, $HOME
discos removibles: MP-3, discos USB, ...
Los datos son montones de bits
se pueden interpretar como bytes
de 8 en 8 bits
byte b
se pueden interpretar como caracteres
de 16 en 16 bits
char c
21.3.2007
entrada / salida + e3
2
1
Ficheros
java.util.File
File fichero= new File(“nombre”);
File fichero= new File(“directorio”, “fichero”);
métodos útiles
boolean exists()
String getName()
String getPath()
http://java.sun.com/j2se/1.5.0/docs/api/java/io/File.html
21.3.2007
entrada / salida + e3
3
Uso de ficheros
Lectura
1.
2.
3.
Escritura
open
read
read
...
close
se abre para leer
se leen porciones
se cierra
1.
2.
3.
open
write
write
...
close
se abre para escribir
se escriben porciones
se cierra
NOTA: si no se cierra,
pueden quedar partes sin guardar
21.3.2007
entrada / salida + e3
4
2
Lectura de bytes
private static final int PORCION= 1024;
String ficheroEntrada= ...
InputStream entrada = new FileInputStream(ficheroEntrada);
byte[] datos = new byte[PORCION];
int nDatos = entrada.read(datos);
while (nDatos > 0) {
// datos [ 0 a nDatos-1 ]
nDatos = entrada.read(datos);
}
entrada.close();
NOTA: aunque se pide leer una PORCION de datos,
puede que se lean menos
21.3.2007
entrada / salida + e3
5
Escritura de bytes
String ficheroSalida= ...
OutputStream salida = new FileOutputStream(ficheroSalida);
while ( ... ) {
byte[] datos = ...
salida.write(datos);
}
salida.close();
NOTA: si no se cierra,
pueden quedar partes sin guardar
21.3.2007
entrada / salida + e3
6
3
Lectura de caracteres
private static final int PORCION= 1024;
String ficheroEntrada= ...
Reader entrada = new FileReader(ficheroEntrada);
char[] datos = new char[PORCION];
int nDatos = entrada.read(datos);
while (nDatos > 0) {
// datos [ 0 a nDatos-1 ]
nDatos = entrada.read(datos);
}
entrada.close();
NOTA: aunque se pide leer una PORCION de datos,
puede que se lean menos
21.3.2007
entrada / salida + e3
7
Escritura de caracteres
String ficheroSalida= ...
Writer salida = new FileWriter(ficheroSalida);
while ( ... ) {
char[] datos = ...
salida.write(datos);
}
salida.close();
NOTA: si no se cierra,
pueden quedar partes sin guardar
21.3.2007
entrada / salida + e3
8
4
Ejercicio e3
Se trata de implementar un cifrador/descifrador
que trabaje con ficheros, siguiendo los algoritmos
de Vigenère
Hay que tener en cuenta:
Los ficheros pueden ser muy grandes,
por lo que no es recomendable implementaciones de
Vigenère “de un paso”
(que podrían dejar la máquina sin memoria)
Los ficheros binarios tienen bytes que no pertenecen al
alfabeto usado por Vigenère
(ej. ficheros .jpg, .mp3)
21.3.2007
entrada / salida + e3
9
Ejercicio e3
Material proporcionado
C: \ java \ lprg \ e3 \ cifrador \ Vigenere.java
C: \ java \ lprg \ e3 \ cifrador \ CifradorIncremental.java
C: \ java \ lprg \ e3 \ cifrador \
DescifradorIncremental.java
C: \ java \ lprg \ e3 \ base64 \ Codificador.java
C: \ java \ lprg \ e3 \ base64 \ Descodificador.java
C: \ java \ lprg \ e3 \ log \ Logger.java
El alumno
C: \ java \ lprg \ e3 \ cifrador \ ui \ CifradorFicheros.java
21.3.2007
entrada / salida + e3
10
5
Ejercicio e3
/**
* Utilización desde consola.
consola.
* Para cifrar fichero:
fichero:
* java cifrador.ui.CifradorFicheros -c clave fichero fichero.vgn
* Para descifrar fichero.vgn:
fichero.vgn:
* java cifrador.ui.CifradorFicheros -d clave fichero.vgn fichero
*
* @param
@param args para indicar cifrar/descifrar,
cifrar/descifrar,
clave, ficheros de entrada y salida
* @throws java.io.IOException si se producen errores
en el tratamiento de ficheros.
ficheros.
*/
21.3.2007
entrada / salida + e3
11
Ejercicio e3
Hay que entregar
$HOME \ lprg \ e3 \ cifrador \ ui \ CifradorFicheros.java
Antes del
viernes, 30 de marzo, a las 24:00
El codigo tiene que
venir perfectamente documentado (javadoc)
trazas
21.3.2007
entrada / salida + e3
12
6
Cifrador incremental
Para cifrar/descifrar textos de gran tamaño (por ej.
ficheros) es recomendable utilizar una
implementación incremental de Vigenère:
Secuencia de uso para cifrar/descrifrar:
1. lee un bloque de N caracteres
2. cifra/descifra con Vigenére
3. repite con otro bloque hasta terminar
21.3.2007
entrada / salida + e3
13
Cifrador incremental
Variante del cifrador de Vigenere
Trabaja sobre String sucesivas,
sin volver a la clave inicial
public class CifradorIncremental {
public CifradorIncremental(String clave) { ... }
public String cifra(String texto) { ... }
}
21.3.2007
entrada / salida + e3
14
7
Descifrador incremental
Variante del descifrador de Vigenere
Trabaja sobre String sucesivas,
sin volver a la clave inicial
public class DescifradorIncremental {
public DescifradorIncremental(String clave) { ... }
public String descifra(String texto) { ... }
}
21.3.2007
entrada / salida + e3
15
CifradorIncremental
21.3.2007
entrada / salida + e3
16
8
Cifrado de bytes
Vigenère sólo cifra mensajes dentro del alfabeto
Base64 codifica cualquier secuencia de bytes
convirtiéndola en un texto dentro del alfabeto:
private static final String ALFABETO =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstu
vwxyz0123456789+/";
Para cifrar cualquier dato (secuencia de bytes):
bytes
base64
texto
Vigenére
criptograma
clave
21.3.2007
entrada / salida + e3
17
Base64
Una forma de meter bits en caracteres “normales”
Un byte son 8 bits
3 bytes son 24 bits
24 bits son 4 códigos de 6 bits
con 6 bits se tienen 26 combinaciones (64)
cada código se asigna a un carácter de
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn
opqrstuvwxyz0123456789+/“
Si faltan bytes, se rellena con “=“
21.3.2007
entrada / salida + e3
18
9
base64
Secuencia de uso:
1.
new Codificador()
2.
se llama N veces a codifica(byte[])
3.
se llama a termina()
21.3.2007
Secuencia de uso:
1.
new Descodificador()
2.
se llama N veces a descodifica (String)
entrada / salida + e3
19
Codificador base64
Se le pasan bytes
devuelve Strings codificadas
public class Codificador {
public Codificador() { ... }
public String codifica(byte[] data) { ... }
public String codifica(byte[] data,
int from, int length) { ... }
public String termina() { ... }
}
21.3.2007
entrada / salida + e3
20
10
Descodificador base64
Se le pasan Strings
devuelve bytes
public class Descodificador {
public Descodificador() { ... }
public byte[] descodifica(String data) { ... }
public byte[] descodifica(String data,
int from, int length) { ... }
}
21.3.2007
entrada / salida + e3
21
Cifrador de ficheros
Para cifrar cualquier fichero:
fichero
texto
InputStream
byte[]
CifradorIncremental
base64.Codificador
criptograma
Writer
texto
fichero.vgn
clave
Para descifrar un fichero.vgn:
fichero
texto
OutputStream
byte[]
DescifradorIncremental
base64.Descodificador
criptograma
Reader
texto
fichero.vgn
clave
21.3.2007
entrada / salida + e3
22
11
E3: cifrar ficheros
1.
2.
3.
4.
5.
Se prepara un codificador Base64
Se prepara un cifrador incremental
Se abre un fichero de bytes de lectura
Se abre un fichero de caracteres de escritura
mientras hay bytes
1.
2.
3.
4.
6.
se lee una PORCION de bytes
se codifican en base64
se cifran
se escriben
Se cierran los ficheros
21.3.2007
entrada / salida + e3
23
E3: descifrar ficheros
1.
2.
3.
4.
5.
Se prepara un descodificador Base64
Se prepara un descifrador incremental
Se abre un fichero de caracteres de lectura
Se abre un fichero de bytes de escritura
mientras hay caracteres
1.
2.
3.
4.
6.
se lee una PORCION de caracteres
se descifran
se descodifican en base64
se escriben
Se cierran los ficheros
21.3.2007
entrada / salida + e3
24
12
E3: trazas
Debe el alumno
Crear un Logger de nombre
"cifrador.ui.CifradorFicheros"
Generar un traza a nivel INFO que indique:
si se está cifrando o descifrando,
la clave utilizada
y los nombres de los ficheros de entrada y de salida
Generar trazas a nivel FINE cada vez que se lea un
bloque de datos del fichero de entrada, indicando
el número total de datos (bytes o caracteres) leídos
hasta el momento.
21.3.2007
entrada / salida + e3
25
13
Descargar