Forneça as classes decoradoras EncryptingWriter e DecryptingReader que codificam e decodificam os caracteres do leitor ou gravador que estiver por trás. Garanta que essas classes são também leitores e gravadores, de maneira que seja possível acrescentar novas decorações. Para a codificação, use o Caesar cipher, que desloca o alfabeto de três caracteres (isto é, A se transforma em D, B se transforma em E, e assim por diante) (Horstmann, 2007).
Horstmann, Cay. (2007). Padrões e Projeto Orientados a Objeto. 2ª edição. Porto Alegre: Bookman. 424 páginas.
/**
* Copyright (C) 2009/2025 - Cristiano Lehrer (cristiano@ybadoo.com.br)
* Ybadoo - Solucoes em Software Livre (www.ybadoo.com.br)
*
* Permission is granted to copy, distribute and/or modify this document
* under the terms of the GNU Free Documentation License, Version 1.3
* or any later version published by the Free Software Foundation; with
* no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
* A copy of the license is included in the section entitled "GNU
* Free Documentation License".
*/
package com.ybadoo.tutoriais.poo;
import java.io.IOException;
import java.io.Writer;
/**
* Cifrar um fluxo de caracteres com a Cifra de Cesar
*/
public class EncryptingWriter extends Writer
{
/**
* Chave da Cifra de Cesar
*/
private int key;
/**
* Fluxo de caracteres de saida
*/
private Writer out;
/**
* Construtor para inicializar o fluxo de caracteres de saida
*
* @param out fluxo de caracteres de saida
*/
public EncryptingWriter(Writer out)
{
this(out, 3);
}
/**
* Construtor para inicializar o fluxo de caracteres de saida e a chave da Cifra de Cesar
*
* @param out fluxo de caracteres de saida
* @param key chave da Cifra de Cesar
*/
public EncryptingWriter(Writer out, int key)
{
super();
this.out = out;
this.key = key % 95;
}
/* (non-Javadoc)
* @see java.io.Writer#append(char)
*/
public EncryptingWriter append(char c) throws IOException
{
this.out.append(encode(new Character(c).toString()).charAt(0));
return this;
}
/* (non-Javadoc)
* @see java.io.Writer#append(java.lang.CharSequence)
*/
public EncryptingWriter append(CharSequence csq) throws IOException
{
this.out.append(encode(new String(csq.toString())).subSequence(0, csq.length()));
return this;
}
/* (non-Javadoc)
* @see java.io.Writer#append(java.lang.CharSequence, int, int)
*/
public EncryptingWriter append(CharSequence csq, int start, int end) throws IOException
{
this.out.append(encode(new String(csq.toString())).subSequence(0, csq.length()), start, end);
return this;
}
/* (non-Javadoc)
* @see java.io.Writer#close()
*/
public void close() throws IOException
{
this.out.close();
}
/**
* Cifrar o texto pela Cifra de Cesar
* @param str texto normal
* @return texto cifrado
*/
private String encode(String str)
{
StringBuilder encoded = new StringBuilder();
for(char ch: str.toCharArray())
{
if((ch >= 32) && (ch <= 126))
{
if((ch + this.key) <= 126)
{
encoded.append((char)(ch + this.key));
}
else
{
encoded.append((char)(ch + this.key - 95));
}
}
else
{
encoded.append(ch);
}
}
return encoded.toString();
}
/* (non-Javadoc)
* @see java.io.Writer#flush()
*/
public void flush() throws IOException
{
this.out.flush();
}
/* (non-Javadoc)
* @see java.io.Writer#write(char[])
*/
public void write(char[] cbuf) throws IOException
{
this.out.write(encode(new String(cbuf)).toCharArray());
}
/* (non-Javadoc)
* @see java.io.Writer#write(char[], int, int)
*/
public void write(char[] cbuf, int off, int len) throws IOException
{
this.out.write(encode(new String(cbuf)).toCharArray(), off, len);
}
/* (non-Javadoc)
* @see java.io.Writer#write(int)
*/
public void write(int c) throws IOException
{
this.out.write(encode(new Integer(c).toString()));
}
/* (non-Javadoc)
* @see java.io.Writer#write(java.lang.String)
*/
public void write(String str) throws IOException
{
this.out.write(encode(str));
}
/* (non-Javadoc)
* @see java.io.Writer#write(java.lang.String, int, int)
*/
public void write(String str, int off, int len) throws IOException
{
this.out.write(encode(str), off, len);
}
}
/**
* Copyright (C) 2009/2025 - Cristiano Lehrer (cristiano@ybadoo.com.br)
* Ybadoo - Solucoes em Software Livre (www.ybadoo.com.br)
*
* Permission is granted to copy, distribute and/or modify this document
* under the terms of the GNU Free Documentation License, Version 1.3
* or any later version published by the Free Software Foundation; with
* no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
* A copy of the license is included in the section entitled "GNU
* Free Documentation License".
*/
package com.ybadoo.tutoriais.poo;
import java.io.IOException;
import java.io.Reader;
import java.nio.CharBuffer;
/**
* Descifrar um fluxo de caracteres com a Cifra de Cesar
*/
public class DecryptingReader extends Reader
{
/**
* Fluxo de caracteres de entrada
*/
private Reader in;
/**
* Chave da Cifra de Cesar
*/
private int key;
/**
* Construtor para inicializar o fluxo de caracteres de entrada
*
* @param in fluxo de caracteres de entrada
*/
public DecryptingReader(Reader in)
{
this(in, 3);
}
/**
* Construtor para inicializar o fluxo de caracteres de entrada e a chave da Cifra de Cesar
*
* @param in fluxo de caracteres de entrada
* @param key chave da Cifra de Cesar
*/
public DecryptingReader(Reader in, int key)
{
super();
this.in = in;
this.key = key % 95;
}
/* (non-Javadoc)
* @see java.io.Reader#close()
*/
public void close() throws IOException
{
this.in.close();
}
/**
* Decifrar o texto pela Cifra de Cesar
* @param str texto a ser decifrado
*/
private void decode(char[] cbuf)
{
for(int i = 0; i < cbuf.length; i++)
{
if((cbuf[i] >= 32) && (cbuf[i] <= 126))
{
if((cbuf[i] - this.key) >= 32)
{
cbuf[i] = (char)(cbuf[i] - this.key);
}
else
{
cbuf[i] = (char)(cbuf[i] - this.key + 95);
}
}
}
}
/* (non-Javadoc)
* @see java.io.Reader#mark(int)
*/
public void mark(int readAheadLimit) throws IOException
{
this.in.mark(readAheadLimit);
}
/* (non-Javadoc)
* @see java.io.Reader#markSupported()
*/
public boolean markSupported()
{
return this.in.markSupported();
}
/* (non-Javadoc)
* @see java.io.Reader#read()
*/
public int read() throws IOException
{
char[] buffer = new char[1];
buffer[0] = (char)this.in.read();
decode(buffer);
return buffer[0];
}
/* (non-Javadoc)
* @see java.io.Reader#read(char[])
*/
public int read(char[] cbuf) throws IOException
{
int retorno = this.in.read(cbuf);
decode(cbuf);
return retorno;
}
/* (non-Javadoc)
* @see java.io.Reader#read(char[], int, int)
*/
public int read(char[] cbuf, int off, int len) throws IOException
{
int retorno = this.in.read(cbuf, off, len);
decode(cbuf);
return retorno;
}
/* (non-Javadoc)
* @see java.io.Reader#read(java.nio.CharBuffer)
*/
public int read(CharBuffer target) throws IOException
{
CharBuffer charBuffer = CharBuffer.allocate(target.capacity());
int retorno = this.in.read(charBuffer);
char[] buffer = charBuffer.array();
decode(buffer);
target.put(buffer);
return retorno;
}
/* (non-Javadoc)
* @see java.io.Reader#ready()
*/
public boolean ready() throws IOException
{
return this.in.ready();
}
/* (non-Javadoc)
* @see java.io.Reader#reset()
*/
public void reset() throws IOException
{
this.in.reset();
}
/* (non-Javadoc)
* @see java.io.Reader#skip(long)
*/
public long skip(long n) throws IOException
{
return this.in.skip(n);
}
}
/**
* Copyright (C) 2009/2025 - Cristiano Lehrer (cristiano@ybadoo.com.br)
* Ybadoo - Solucoes em Software Livre (www.ybadoo.com.br)
*
* Permission is granted to copy, distribute and/or modify this document
* under the terms of the GNU Free Documentation License, Version 1.3
* or any later version published by the Free Software Foundation; with
* no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
* A copy of the license is included in the section entitled "GNU
* Free Documentation License".
*/
package com.ybadoo.tutoriais.poo;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.PrintWriter;
/**
* Programa de teste dos decoradores para a Cifra de Ceaser
*/
public class Application
{
/**
* Metodo principal da linguagem de programacao Java
*
* @param args argumentos da linha de comando (nao utilizado)
*/
public static void main(String[] args)
{
try
{
PrintWriter out = new PrintWriter(
new BufferedWriter(
new EncryptingWriter(new FileWriter("teste.txt", true), 12)));
out.println("the quick brown fox jumped over the lazy dog");
out.println("abcdefghijklmnopqrstuvwxyz");
out.println("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
out.println("0123456789");
out.close();
LineNumberReader in = new LineNumberReader(
new BufferedReader(
new DecryptingReader(new FileReader("teste.txt"), 12)));
System.out.println(in.readLine());
System.out.println(in.readLine());
System.out.println(in.readLine());
System.out.println(in.readLine());
in.close();
}
catch(IOException exception)
{
exception.printStackTrace();
}
}
}