ααα ααααΈααααΆα
ααααΆααααα
αα·αααΌαααα»ααααΆααα αααααααααα»ααααα»ααα·ααααΆαα
ααααα·ααααΆααα ααΆααααααα·ααααΆαα½ααααα»ααα·ααααΆααΆ "αα·ααΈααΆααααααααααααααααα»ααααα·ααΆαααααααΆα"α αα·α
αα
ααΆααααααΌαα±ααααΎααααααΎααααααα·ααΈαααααααααααΆααα
αααα»αα―αααΆα GIF α αααα»αααΆααααααα
α
α·αααααααΎααΆαα
Java α
αα αααα»αα’αααααααα αααα»αααΉααααααΆααα’αααΈα ααα»α ααααΉααααΈαα½αα ααα½α ααααΌα ααΆααααααααααααα·ααΈααΌα αα½ααααααααΌαααΆααααααΎαα‘αΎαα
αααααααααΉααααΈ
αααααα GIF
GIF (Graphics Interchange Format - αααααααααΆααααααΆααααααΆααααααΌαααΌαααΆα) ααΊααΆαααααααααααΆαααααααΆαα»αααΌαααΆαααααΆα ααα·α αααααΆααααααααΆααααααΆαα»ααα·αααααααααααΆααααα αΆααααααα·αααΆααααααα»αααΆααααα»ααααααααα αΌαααα 256 αααα αααααααααΆααααααααΌαααΆααααααΎαα‘αΎααααα»αααααΆα 1987 (GIF87a) ααα CompuServe αααααΆαααααααΌαααΌαααΆα raster ααΎαααααΆαα αα ααααΆα 1989 ααααααααααΌαααΆααααααα (GIF89a) ααΆαααΆαααααααααΆαααααααΆααΆα αα·αα αααΆααααΌαααΆαααααααα
α―αααΆα GIF ααΆααα ααΆαααααααααααα»αα αααα»αααΆααααααααααααΆαααααααααα (α¬ααΆα’αΆαααααααΎααααα½αα ααα½α) ααΌα ααααααΆααααΎααααα·αα’αΆα αα αα½α αααααα»αααΆαααααΎα±ααααΆαααα α»αα’αααΈααααααααααααα»αααΈαα½αααααα·ααα α αα ααΆααααααααααααΌαααΆα GIF ααααα·αααΆαα αααΆααΆαααααααα»ααααα»ααααααα GIF89aα
αααα»αα
αααααααα»αααΆααα’αααααα
ααΆαααααααα αααα»αααααΈαααααΎαααΉαα
αΆααα’αΆααααααααΎαααα»αααααΆαααΆαααΆααα αα·ααααΆαααΆαααααααααααα½ααα»αααααΌαα
ααααααααΆαααΆαα
CT
- ααααααΆαααααααΆαααΆααααα ααααα·αααΎααααααααααΌαααΆαααααα ααααΆαααΆααααααααΌαααα αΆααααααΎαααααΆαααααααΆααααΈα ααα»α ααΆαα’ααααααα‘αΌααΈαααSize
- ααα αααααΆαααΆα αα·αα ααα½αααααααα»αααΌαααΆαα ααααααααααΆαααααΆαααΆαααααααααα
ααα α
α
ααα½αααα
ααα αααααΆαααΆα, αα
7
256
768
6
128
384
5
64
192
4
32
96
3
16
48
2
8
24
1
4
12
0
2
6
αα·ααΈααΆαααααα’αα·αααααΈα
αα·ααΈααΆαααααααΆααααααααΉαααααΌαααΆαααααΎααΎααααΈα’αα·αααααΈαααΆααα αααα»αα―αααΆαααΌαααΆαα
- αα·ααΈααΆααααα LSB (Least Significant Bit)
- αα·ααΈααΆαααααααααααααααΆαααΆα
αα·ααΈααΆααααα LSB - αα·ααΈααΆαααααααΌαα αα steganography α ααΆααΆαααΆααααα½ααααΈαααααΆαααα α»αααααααα αααα»ααα»αααΊααα (αααα»αααααΈααααααΎα ααααααΆαααΆαααα) ααΆαα½αααΉααααΈαααααΆααααααΆααα
αααααα·ααΈααΉαααααΎααΈααααΈαα α»αααααααα αααα»αααααααααΆαααΆααααααΆααααααααα·ααΈααΆααααααααα αααααΆααααααΆαααααΆααααΌαααΆα 24 αααΈα αααααααΆαααΆααααααΆαααΈαααααααΆαααααα α ααα αα·ααααα αααααΆααααΈαααα αΌαααΆααα αααα»αααΆ αααΆαααΆαα»αααααΈαα½ααααΉαααααΆααααααΌααααααααα·αα’αα·ααααΆ 3/255 α ααΆαααααΆααααααΌααααααα ααΈαα½αααΉαααΎααα·αααΎα α¬αα·ααΆαααααααααΆααα αααααααααααα»ααα α αΎαααΈααΈαααΆααΉααα·αα’αΆα ααΎαααΎααα ααΎα§ααααααααα ααααααααΆααααααΆααα»αααΆαααΆααααααα
α ααα½αααααααΆαααΉαα’αΆααααααααααααΆαααα ααΎααα αααααααΆαααΆαααΌαααΆαα αααααΆαααα αα’αα·ααααΆααααααΆαααΆαααΊ 256 ααα α αΎαααααα·αααΎαααΈαααΆαααΈαααααΌαααΆαααααααα αααα»ααααΆαααΆαα»αααααααΈαα½αα αααααααααααΆαα’αα·ααααΆ (ααΆαα½αααΉαααααΆαααΆαα’αα·ααααΆαααα»αααΌαααΆα) ααΊ 192 ααα αα ααααααααΆαααααΌαααΆααααααααααα»αααΌαααΆα ααα αα―αααΆααα·αααααΆααααααΌαααα
αα·ααΈααΆααααααααααΈαααααΆαααΆααααααααΎαααΆααααααΆαααααα ααΆαααααααα GIF ααα»αααααα ααΆααΉαααΆαααααα·αααααΆααααα»αααΎααΌαααΆααααααΆαααααΆαααΆαααΌα α ααααΉαααΆαααααααΆααΊααΆααΆαααααΎαααα αααααααΆαααΆααααα ααα»ααααααααααΌαααα ααααααααααααΆααααΆαααααααααααα αΆαααΆα ααααα½ααααααα ααααα·αααΎααΎααα·α αΆαααΆααΆααα αα’αααααααΆααααααΆαααΆαααΊ 2 ααα (6 αα) αααααα αα’αα·ααααΆααααΆααααααΆαααααααα’αΆα ααΆα 256 Γ 3β6 = 762 ααα αα»ααα·ααααα·ααΊαα»ααααα·ααΆαααααΈαααααΈαααΆα ααΆααααααΆαααααααα’αΆα ααααΌαααΆαα’αΆααααααααΎαααααα·ααΈαα·ααααα’αααααααΆαα½α ααααα·αααΎααΆααα·αααααΌαααΆαααα½αααααΌαααΆαα’αα·αααααΈαααααααα
αααααααΆααααααα
ααΆααα ααΆαααααα·ααΈ
α§αααααα
αΆαααΆα
αααΆααα’αααααααΆααα’αα»αααααααα½ααααααααΆαααΆαα’αα·αααααΈα αα·αααΆααα·ααααΈαααΉαααααΌαααΆααα½ααααα
αΌααα
αααα»ααααα
αα com.tsarik.steganography
. αααα
ααααααα½ααααα
αΌαα
ααα»α
αααααΆαα Encryptor
ααΆαα½αααΉααα·ααΈααΆααααα encrypt
ΠΈ decrypt
, ααααΆαα Binary
ααααααααααΌααααααααΆααααα»αααΆαααααΎααΆαααΆαα½αα’αΆαααααΈα ααααΌα
ααΆααααΆααααΎαααα UnableToEncryptException
ΠΈ UnableToDecryptException
ααααα½αααααΎαααα»ααα·ααΈααΆαααααα
ααα»α
αααααΆαα Encryptor
αααα»αααααΈααΆαααα α»ααααα»αααΆαα’αα·αααΌα αα·ααα·ααΌααααααααα½αα
αααα
αααααααα·ααΈααααΆαα com.tsarik.programs.gifed
ααΉααα½ααααα
αΌαααααΆαααααααα·ααΈαααα’αΆα
ααααΎαααΆαααΆαααΆαα½αααΉααα·ααΈααΆααααααα·αα·αααα main
α’αα»ααααΆαα±ααα’αααααααΎαααΆααααααα·ααΈ; ααααΆααααααααααΆαα»ααααΆαααΆαααααααααααα·ααΈ; αα·ααααα
ααααΆαα½αααααΆααααααααααα
ααΆαα’αα»αααααααα½ααααααααΆαααααααα½αα―αααΉαααααΌαααΆααααα αΆααα
αααα»ααααα
αα com.tsarik.programs.gifed.gif
ααααΆαα GIFEncryptorByLSBMethod
ΠΈ GIFEncryptorByPaletteExtensionMethod
. ααααΆααααΆααααΈααααααΉαα’αα»ααααα
ααα»α
αααααΆαα Encryptor
.
αααααα’ααααΎαα ααΆαααααααααααααααααααΆα GIF α’αααα’αΆα αααααΎααααα½ααααααααΆαααΌαα αααααΆααααΆαααααΆαααΆααα αααα»αααααΆαααΆαααΌαααΆαα
ααΎααααΈαααααααααααΆαααααΆααα
αααα»αααΌαααΆα α
αΆαααΆα
αααααΌαααααααααααΆααααΆααααΆαααααααΈααα
ααΎαααΆα αααα§ααααααα·ααΌαα’αΆααα»α αα·ααα·αα·αααααΎαααΆαααααΉαααααΌαα ααααα·αααΎααΆαα·αααααΌαααααΆααα ααΆααααΌαααΆαα
αΆαααα»αααΆαα·αααΆαααΆαααΆαααα
αααα»αααΌαααΆααααααα αααααΆααα’αααααααΌααααααΆααααααααααααΆαα αααααΆααααα’αααααααααΆααααα½αααΆααααΆααα
ααααΆααααΆαααααΆαααααααααα·ααΈααΆααααΌαα
ααΆαα’αα»αααααααααα·ααΈ
ααΆαα’αα»αααααααααα·ααΈααΆααααΌαα’αΆα
αααα
ααααΆααΈααααααα ααΆαα’αα»ααααααΆαα’αα·αααααΈαα
ααα»α
αααααΆαα αα·ααα·ααΈααΆααααααα·ααααΈα Encryptor
, αα
αααα»αααααΆαα GIFEncryptorByLSBMethod
ΠΈ GIFEncryptorByPaletteExtensionMethod
αα·αααΆαα’αα»ααααα
ααα»α
αααααΆααα’αααααααΎα
αα·α
αΆαααΆααααΆαα GIFEncryptorByLSBMethod
.
ααΆα firstLSBit
ΠΈ secondLSBit
ααΆαααααααΈαααααααΈαα½ααααααΌαααΆα αααααΆααα½αααααααΌαααΆααααα
αΌα αα·αααΈαααααααααααΆααα½αααααααΌαααΆαα’αΆαα ααΆα checkSequence
αααααΆαα»αααααΆαα check bit ααΎααααΈααΆααΆααΆαααΌαααΆαααα½αααααΆααααΆααααααΆαααααααα αα·ααΈααΆααααααα·αα·αααα getEncryptingFileParameters
αααα‘αααααΆαααΆααααααααα―αααΆααααααΆααααααΆαα αα·αααααααααααΆααααααΆαα»ααα
αααα½ααααααααΆααα·ααΈααΆααααα encrypt
ΠΊΠ»Π°ΡΡΠ° GIFEncryptorByLSBMethod
:
αα·ααααααΌαααααααΆααα
@Override
public void encrypt(File in, File out, String text) throws UnableToEncodeException, NullPointerException, IOException {
if (in == null) {
throw new NullPointerException("Input file is null");
}
if (out == null) {
throw new NullPointerException("Output file is null");
}
if (text == null) {
throw new NullPointerException("Text is null");
}
// read bytes from input file
byte[] bytes = new byte[(int)in.length()];
InputStream is = new FileInputStream(in);
is.read(bytes);
is.close();
// check format
if (!(new String(bytes, 0, 6)).equals("GIF89a")) {
throw new UnableToEncodeException("Input file has wrong GIF format");
}
// read palette size property from first three bits in the 10-th byte from the file
byte[] b10 = Binary.toBitArray(bytes[10]);
byte bsize = Binary.toByte(new byte[] {b10[0], b10[1], b10[2]});
// calculate color count and possible message length
int bOrigColorCount = (int)Math.pow(2, bsize+1);
int possibleMessageLength = bOrigColorCount*3/4;
int possibleTextLength = possibleMessageLength-2;// one byte for check and one byte for message length
if (possibleTextLength < text.length()) {
throw new UnableToEncodeException("Text is too big");
}
int n = 13;
// write check sequence
for (int i = 0; i < checkSequence.length/2; i++) {
byte[] ba = Binary.toBitArray(bytes[n]);
ba[firstLSBit] = checkSequence[2*i];
ba[secondLSBit] = checkSequence[2*i+1];
bytes[n] = Binary.toByte(ba);
n++;
}
// write text length
byte[] cl = Binary.toBitArray((byte)text.length());
for (int i = 0; i < cl.length/2; i++) {
byte[] ba = Binary.toBitArray(bytes[n]);
ba[firstLSBit] = cl[2*i];
ba[secondLSBit] = cl[2*i+1];
bytes[n] = Binary.toByte(ba);
n++;
}
// write message
byte[] textBytes = text.getBytes();
for (int i = 0; i < textBytes.length; i++) {
byte[] c = Binary.toBitArray(textBytes[i]);
for (int ci = 0; ci < c.length/2; ci++) {
byte[] ba = Binary.toBitArray(bytes[n]);
ba[firstLSBit] = c[2*ci];
ba[secondLSBit] = c[2*ci+1];
bytes[n] = Binary.toByte(ba);
n++;
}
}
// write output file
OutputStream os = new FileOutputStream(out);
os.write(bytes);
os.close();
}
αααα½ααααααααΆα αα·αααΌαααααααααα·ααΈααΆααααα decrypt
ΠΊΠ»Π°ΡΡΠ° GIFEncryptorByLSBMethod
:
@Override
public String decrypt(File in) throws UnableToDecodeException, NullPointerException, IOException {
if (in == null) {
throw new NullPointerException("Input file is null");
}
// read bytes from input file
byte[] bytes = new byte[(int)in.length()];
InputStream is = new FileInputStream(in);
is.read(bytes);
is.close();
// check format
if (!(new String(bytes, 0, 6)).equals("GIF89a")) {
throw new UnableToDecodeException("Input file has wrong GIF format");
}
// read palette size property from first three bits in the 10-th byte from the file
byte[] b10 = Binary.toBitArray(bytes[10]);
byte bsize = Binary.toByte(new byte[] {b10[0], b10[1], b10[2]});
// calculate color count and possible message length
int bOrigColorCount = (int)Math.pow(2, bsize+1);
int possibleMessageLength = bOrigColorCount*3/4;
int possibleTextLength = possibleMessageLength-2; // one byte for check and one byte for message length
int n = 13;
// read check sequence
byte[] csBits = new byte[checkSequence.length];
for (int i = 0; i < 4; i++) {
byte[] ba = Binary.toBitArray(bytes[n]);
csBits[2*i] = ba[firstLSBit];
csBits[2*i+1] = ba[secondLSBit];
n++;
}
byte cs = Binary.toByte(csBits);
if (cs != Binary.toByte(checkSequence)) {
throw new UnableToDecodeException("There is no encrypted message in the image (Check sequence is incorrect)");
}
// read text length
byte[] cl = new byte[8];
for (int i = 0; i < 4; i++) {
byte[] ba = Binary.toBitArray(bytes[n]);
cl[2*i] = ba[firstLSBit];
cl[2*i+1] = ba[secondLSBit];
n++;
}
byte textLength = Binary.toByte(cl);
if (textLength < 0) {
throw new UnableToDecodeException("Decoded text length is less than 0");
}
if (possibleTextLength < textLength) {
throw new UnableToDecodeException("There is no messages (Decoded message length (" + textLength + ") is less than Possible message length (" + possibleTextLength + "))");
}
// read text bits and make text bytes
byte[] bt = new byte[textLength];
for (int i = 0; i < bt.length; i++) {
byte[] bc = new byte[8];
for (int bci = 0; bci < bc.length/2; bci++) {
byte[] ba = Binary.toBitArray(bytes[n]);
bc[2*bci] = ba[firstLSBit];
bc[2*bci+1] = ba[secondLSBit];
n++;
}
bt[i] = Binary.toByte(bc);
}
return new String(bt);
}
ααΆαα’αα»ααααααααΆαα GIFEncryptorByPaletteExtensionMethod
ααΉαααααααααααΆ ααΆααααα·ααΈαααααΆαα»α/α’αΆαααααααΆαααα»αααααααααα»αααααΆα
αα
αααα»αααααΆαα MainFrame
αα·ααΈααΆααααααα»αααααΌαααΆααα·αααααΆα encryptImage(Encryptor encryptor)
ΠΈ decryptImage(Encryptor encryptor)
ααααΎαααΆααααααααααα·ααΈααΆαααααα
ααα»α
αααααΆαα Encryptor
αα·αααΆαααααΆαααααααΆααααααΆαα½αα’αααααααΎααααΆαα α§. ααΎααααα’ααααααΎαααΎαα―αααΆα αααα αΆαααΆαααα α»αααα ααααΌα
ααΆαα·ααΈααΆααααααααααααα: openImage()
α’αα»ααααΆαα±ααα’αααααααΎααααΎαααΎαααΌαααΆα exit()
αααα
ααααΈαααααα·ααΈα αα·ααΈααΆαααααααΆαααααααααΌαααΆαααα α
ααΆ Action
ααΆαα»αααΊαα»ααααααααΌαααααΆα ααααΆαααααααααααααΎαα·ααΈααΆααααααααα½αα createComponents()
- ααΆααααααΎααααΆαααΆαα»αααααα, loadImageFile(File f)
- αααα»αααΌαααΆααα
αααα»ααααΆαααΆαα»αα·αααααΈα―αααΆαα ααΆαα’αα»ααααααααΆαα GIFEncryptorByPaletteExtensionMethod
ααααααααΉαααΆαα’αα»ααααααααΆαα GIFEncryptorByLSBMethod
ααΆααα»αααααΆααααΆααααΊαα
αααα»ααα·ααΈαααααααΆαααααΌαααΆαααααα αα·αα’αΆαααΈααααΆαααΆαα
ααααα·ααααα·ααΆααααααα·ααΈ
αα·ααΈααΆααααα LBS
α§αααΆααΆααΆαααΌαααΆαααΌα αααα
αα
αααα»αααΌαααΆαααα ααααΆαααΆαααΆα 256 ααα (ααΌα
αααααααΆαααΆααααααΆαα»α)α αα½ααααααααΌαααΊαααααααα
αααα αααααα αααααααααααααΊαααα
α ααααΆαααααΈαααααΆαααΆαααΆαααααΉαααΆαααΌα
ααΆααααααα
11111111 11111111 11111111 00000000 00000000 00000000 11111111 00000000 00000000 00000000 11111111 00000000...
αα
ααααααααΆαααααΌαααΆααααααα αααΈααααααΌααααααΆααααΈαααααααΉαααααΌαααΆααααα½αααααααΈαααΈααΆαα ααΌαααΆαααααααααΊααααΎααααα·ααα»αααΈααΎαα
ααΎα
ααΌαααΆαααΆαα½αααΆααααααΆααααααα
αα·ααΈααΆααααααααααΈαααααΆαααΆα
αα αααα’αααααΎαααΌαααΆααααααΆαααΆααααααααΎαα·ααΈααα α’αααααΉαααΎαααΌαααΆαααΆααααααα
ααΆα
αααΆααααΆααααΆαα·ααΈααΆααααααααααΉααα·αααααΎαααΆααααααΆαααααααααΆαα
αΆααααααααααααα α αΎαα’αΆα
ααααΌαααΆαααΆαα’αα·αααααΈαααΆαααααααα
ααΆαα’αα·αααααΈα/αα·ααααΈααα αααα»αααΌαααΆαααΆαα αααΆααααΎαααΆαααΌα αα αααα»αααΌαααΆααα·αα·ααααααααααΆααα ααα»ααααα αααΆαα·αααΌα ααα
ααααααααααΆαααααΎα
http://ru.wikipedia.org/wiki/Gif http://ru.wikipedia.org/wiki/Π‘ΡΠ΅Π³Π°Π½ΠΎΠ³ΡΠ°ΡΠΈΡ http://home.onego.ru/~chiezo/gif.htm
ααΆααα
ααααα: www.habr.com