Pessoal, tava dando uma olhada na Ascii Table, e tava mandando imprimir os valores de cada letra para teste:
int byteValue = 'B';
System.out.println("Valor Byte" + byteValues);
Depois, eu tento voltar para a letra assim:
String str = Integer.toBinaryString((byte) byteValue);
int i = Integer.parseInt(str, 2);
System.out.println((char) i);
Para todos os valores da taebla funcionam, mas para caracteres especiais não (do tipo á,à,â,ã,ä,ç).
Dá esse erro: [color=red]Exception in thread “main” java.lang.NumberFormatException: For input string: “11111111111111111111111111000111”[/color]
Se eu faço assim: char b3 = (char) (byteValue);
Funciona, mas ae ele vai pegar de todos os pixels da imagem, inclusive os que eu não quero… Estou usando ele, mas como que eu faço para parar o algoritimo de varredura da imagem quando terminar a frase??
A imagem que estou falando é essa: http://www.guj.com.br/posts/list/15/221333.java
O problema é que caracteres especiais, caracteres estrangeiros, simbolos, etc, seguem a tabela Unicode, e não a tabela ascii. É por isso que o char, no Java, tem 2 bytes e não 1.
Uma das formas de resolver isso é você parar de lidar com strings, e passar a lidar com o texto byte-a-byte, como se fosse um arquivo binário. E depois fazer o mesmo para recompor. Agora, seu texto ocupará o dobro do espaço, o que exigirá uma imagem duas vezes maior.
Por isso, além de tratar byte-a-byte, recomendo que você use um inputstream com compactação.
Agora estou com um problema: Saber quando parar de pegar texto da imagem
Eu fiz o seguinte: No primeiro pixel (0,0) eu do um setRed com o tamanho do texto…
Depois na hora de descriptografar eu volto lá e do um getRed no primeiro pixel…
Funciona certinho… Mas tem 1 problema… Quando o texto tem mais do que 255 caracteres não dá pra dar um setRed com ele…
Pensei em /1000 e depois fazer *1000 mas ele só aceita valor inteiro… Então se tiver 300 caracteres, vai pra 0,3 e volta pra 0…
Color m = new Color(imagem.getRGB(0, 0));
Color newColorr = new Color(text.length(),m.getGreen(),m.getBlue(),m.getAlpha());
imagem.setRGB(0, 0, newColorr.getRGB());
Mas ae da erro quando é mais que 255…
Mas não pode ocorrer coincidentemente de ter um texto com 0 nakeles bits?
int tamanho = img1gp.getRGB(0, 0);
tamanho = -tamanho *2; //* 2 pq é 2 pixels para cada letra
Testei com uns textos grandes aqui e deu certo…
RGB tem limite também? De quanto é?
Eu colokei para criptografar um texto "grandinho" (de 8940 caracteres):
Ele só conseguiu chegar até o 1370, depois deu isso:
[color=red]Exception in thread "Thread-4" java.lang.StackOverflowError
at sun.nio.cs.SingleByteEncoder.encodeArrayLoop(Unknown Source)
at sun.nio.cs.SingleByteEncoder.encodeLoop(Unknown Source)
at java.nio.charset.CharsetEncoder.encode(Unknown Source)
at sun.nio.cs.StreamEncoder.implWrite(Unknown Source)
at sun.nio.cs.StreamEncoder.write(Unknown Source)
at java.io.OutputStreamWriter.write(Unknown Source)
at java.io.BufferedWriter.flushBuffer(Unknown Source)
at java.io.PrintStream.write(Unknown Source)
at java.io.PrintStream.print(Unknown Source)
at java.io.PrintStream.println(Unknown Source)[/color]
Meu método chama ele mesmo várias vezes, deve tar estorando…
[code]private static void start(BufferedImage imagem) {
for (int x = 0; x < size; x++) {
String qual = text.substring(y, y + 1);
if (qual.equals(String.valueOf(letras[x]))) {
System.out.println(letras[x]);
int xd = line + 1;
Color pixel1 = new Color(imagem.getRGB(line, colum));
int r1 = pixel1.getRed() & 0xFC; //Limpa os dois ultimos bit. FC=1111 1100
int g1 = pixel1.getGreen() & 0xFE; //Limpa o ultimo bit. FE=1111 1110
int b1 = pixel1.getBlue() & 0xFE;
Color pixel2 = new Color(imagem.getRGB(xd, colum));
int r2 = pixel2.getRed() & 0xFC;
int g2 = pixel2.getGreen() & 0xFE;
int b2 = pixel2.getBlue() & 0xFE;
/////
int bits = letras[x];
bits = bits & 3;
int novoRED1 = r1 | bits;
bits = letras[x];
bits = bits >>2;
bits = bits & 1;
int novoGREEN1 = g1 | bits;
bits = letras[x];
bits = bits >>3;
bits = bits & 1;
int novoBLUE1 = b1 | bits;
/////////////////////
bits = letras[x];
bits = bits >>4; //5
bits = bits & 3;
int novoRED2 = r2 | bits;
bits = letras[x];
bits = bits >>6;
bits = bits & 1;
int novoGREEN2 = g2|bits;
bits = letras[x];
bits = bits >>7;
bits = bits & 1;
int novoBLUE2 = b2 |bits;
Color newColorr = new Color(novoRED1,novoGREEN1,novoBLUE1,pixel1.getAlpha()); //pixel1.getAlpha()
Color newColorr2 = new Color(novoRED2,novoGREEN2,novoBLUE2,pixel2.getAlpha()); //pixel2.getAlpha()
imagem.setRGB(line, colum, newColorr.getRGB());
imagem.setRGB(xd, colum, newColorr2.getRGB());
line = line + 2;
if (line == imagem.getWidth()) {
colum++;
line = 0;
}
y++;
if (y < text.length()) {
start(imagem); //AKI.. Ele se chama
}
break;
}
}
}[/code]
Ali no (y<text.lenght) ele vai chamar dinovo, até completar o texto…>
Ae! Consegui!
Realmente não precisava ficar se chamando várias vezes…
Mandei criptografar um texto de 20.000 caracteres e deu certinho…
O unico caractere que não sai é o um abre aspas, que quando eu coloko aki no guj vira interrogação… O " sai…
Realmente, não percebesse nenhuma variação na imagem, só no primeiro pixel que é o RGB da quantidade de caracteres… no mais é tudo igualzinho…
Vlws ae vinigodoy, que me ajudou pra caramba mesmo, malz ae por ter enchido tanto o saco! kkkk
=]
Bom, acabei me empolgando e escrevi também meu algoritmo de esteganografia.
Em anexo, está o jar que faz o algoritmo rodar. E uma imagem, com a logo do GUJ.
Para esteganografar:
java -jar Esteganografia.jar -e NomeDaImagem.png NomeDoArquivo1 NomeDoArquivo2 …
Para reverter
java -jar Esteganografia.jar -r NomeDaImagem.png
Experimente rodar o programa para reverter os textos secretos que estão nessa logo.
Os textos saem na forma de arquivos. Então, não tentem só procurar uma frasezinha escrita no console.
Entretanto, esse programa não usa o canal alfa. Uma otimização no PNG as vezes pré-multiplica o canal, o que o inviabiliza para o processo.
No lugar, uso 2 bits do canal vermelho, 1 do verde e 1 do azul para guardar meio byte, o que torna necessário usar 2 pixels para armazenar cada byte do que quero esconder.
tentei com 1 documento .doc, ele gera a imagem, mas na volta ele não gera o texto…
Mas com o logo do guj deu certo…
Bem bacana… Tem bastante coisa que não entendi, mas beleza… Devo ver isso quando entrar na faculdade ! rs
Por enquanto sou apenas um vestibulando rs…
Não faz o menor sentido. O programa nem sequer olha pro formato do arquivo. Ele lê um arquivo byte-a-byte e esconde. Pode ser qualquer coisa.
Você tem certeza que mandou reverter a imagem certa?
Em todo caso, está aqui uma demonstração. Essa imagem contém o doc dos fontes do programa.