Isingeniso
Sanibonani.
Esikhathini esingengakanani esidlule, lapho ngifunda enyuvesi, kwakukhona umsebenzi wesifundo sokuqondisa "Izindlela zeSoftware zokuvikela ulwazi." Umsebenzi ozokwenziwa wawudinga ukuthi sakhe uhlelo olushumeka umlayezo kumafayela e-GIF. Nganquma ukukwenza e-Java.
Kulesi sihloko ngizochaza amaphuzu athile etiyetha, kanye nokuthi lolu hlelo oluncane lwadalwa kanjani.
Ingxenye ethiyori
Ifomethi ye-GIF
I-GIF (Ifomethi Ye-Interchange Format - ifomethi yokushintshisana ngezithombe) iyifomethi yokugcina izithombe eziyingcaca, ekwazi ukugcina idatha ecindezelweyo ngaphandle kokulahlekelwa ikhwalithi ngefomethi efika kumibala engama-256. Le fomethi yasungulwa ngo-1987 (GIF87a) yiCompuServe ukuze idlulise izithombe ezi-raster ngamanethiwekhi. Ngo-1989, ifomethi yashintshwa (GIF89a), ukusekelwa kokubonisa izinto obala nokugqwayiza kwengezwa.
Amafayela e-GIF anesakhiwo sebhulokhi. Lawa mabhulokhi ahlala enobude obunqunyiwe (noma kuncike kwamanye amafulegi), ngakho-ke cishe akunakwenzeka ukwenza iphutha mayelana nokuthi ibhulokhi ngayinye ikuphi. Isakhiwo sesithombe esilula se-GIF esingagqwayiziwe ngefomethi ye-GIF89a:

Kuwo wonke amabhlogo wesakhiwo, kulokhu sizoba nentshisekelo kubhulokhi yephalethi yomhlaba wonke kanye namapharamitha anesibopho sephalethi:
CT- ukuba khona kwephalethi yomhlaba wonke. Uma leli fulegi lisethiwe, iphalethi yomhlaba wonke kufanele iqale ngokushesha ngemva kwesibambo sesikrini esinengqondo.Size— usayizi wephalethi nenani lemibala esithombeni. Amanani ale pharamitha:
Usayizi
Inombolo yemibala
Usayizi wephalethi, amabhayithi
7
256
768
6
128
384
5
64
192
4
32
96
3
16
48
2
8
24
1
4
12
0
2
6
Izindlela zokubethela
Izindlela ezilandelayo zizosetshenziswa ukubethela imilayezo kumafayela esithombe:
- Indlela ye-LSB (Ibhithi Engabalulekile Kancane).
- Indlela yokwengeza i-Palette
Indlela ye-LSB - indlela evamile ye-steganography. Kuhlanganisa ukufaka izingcezu zokugcina ezibalulekile esitsheni (kithi, amabhayithi ephalethi yomhlaba wonke) ngezingcezu zomlayezo ofihliwe.
Uhlelo luzosebenzisa izingcezu ezimbili zokugcina kumabhayithi ephalethi yomhlaba njengengxenye yale ndlela. Lokhu kusho ukuthi esithombeni esingamabhithi angu-24, lapho iphalethi yombala ingamabhayithi amathathu kokubomvu, okuluhlaza okwesibhakabhaka, nokuluhlaza, ngemva kokushumeka umlayezo kuso, ingxenye yombala ngayinye izoshintsha ngesilinganiso esiphezulu esingu-3/255. Ushintsho olunjalo, okokuqala, luyobe lungabonakali noma lube nzima ukulubona ngeso lomuntu, futhi okwesibili, ngeke lubonakale kumadivayisi okukhipha ulwazi olusezingeni eliphansi.
Inani lolwazi lizoncika ngokuqondile kusayizi wephalethi yesithombe. Njengoba ubukhulu bobukhulu bephalethi nemibala engama-256, futhi uma izingcezu zemilayezo ezimbili zibhalwe engxenyeni yombala ngamunye, khona-ke ubude bomlayezo obuningi (obukhulu bephalethi esithombeni) bungamabhayithi angu-192. Uma umlayezo usushumekwe esithombeni, usayizi wefayela awushintshi.
Indlela yokwandisa i-Palette, esebenza kuphela ngesakhiwo se-GIF. Izosebenza kakhulu ezithombeni ezinephalethi elincane. Ingqikithi yayo ukuthi ikhulisa usayizi wephalethi, ngaleyo ndlela inikeze isikhala esengeziwe sokubhala amabhayithi adingekayo esikhundleni samabhayithi ombala. Uma sicabanga ukuthi usayizi omncane wephalethi imibala emi-2 (amabhayithi angu-6), khona-ke ubukhulu bomlayezo oshumekiwe bungaba ngu-256 × 3–6 = 762 bytes. Okubi ukuvikeleka okuphansi kwe-cryptographic; umlayezo oshumekiwe ungafundwa kusetshenziswa noma isiphi isihleli sombhalo uma umlayezo ungazange ufakwe ekubethelweni okwengeziwe.
Ingxenye esebenzayo
Umklamo wohlelo
Wonke amathuluzi adingekayo wokusebenzisa ama-algorithms wokubethela kanye nokususa ukubethela azofakwa kuphakheji com.tsarik.steganography. Le phakheji ihlanganisa isixhumi esibonakalayo Encryptor ngezindlela encrypt и decrypt, Ikilasi Binary, okunikeza amandla okusebenza ngama-bit arrays, kanye namakilasi ahlukile UnableToEncryptException и UnableToDecryptException, okufanele isetshenziswe ezindleleni ze-interface Encryptor uma kuba namaphutha ombhalo wekhodi nawokukhipha amakhodi ngokulandelanayo.
Iphakheji yohlelo oluyinhloko com.tsarik.programs.gifed izofaka ikilasi lohlelo olusebenzisekayo ngendlela emile main, okukuvumela ukuthi uqalise uhlelo; ikilasi eligcina amapharamitha wohlelo; namaphakheji namanye amakilasi.
Ukuqaliswa kwama-algorithms ngokwawo kuzokwethulwa kuphakheji com.tsarik.programs.gifed.gif amakilasi GIFEncryptorByLSBMethod и GIFEncryptorByPaletteExtensionMethod. Zombili lezi zigaba zizosebenzisa isixhumi esibonakalayo Encryptor.
Ngokusekelwe esakhiweni sefomethi ye-GIF, ungakha i-algorithm evamile yokwethula umlayezo kuphalethi yesithombe:

Ukuze unqume ukuba khona komlayezo esithombeni, kuyadingeka ukwengeza ukulandelana okuthile kwamabhithi ekuqaleni komlayezo, idikhoda eyifunda kuqala bese ihlola ukufaneleka. Uma ingahambisani, khona-ke kubhekwa ukuthi awukho umlayezo ofihliwe esithombeni. Okulandelayo udinga ukucacisa ubude bomlayezo. Bese kuba umbhalo womlayezo ngokwawo.
Umdwebo wekilasi walo lonke uhlelo lokusebenza:

Ukuqaliswa kohlelo
Ukuqaliswa kwalo lonke uhlelo kungahlukaniswa izingxenye ezimbili: ukuqaliswa kokubethela kokusetshenziswa kubonwa kanye nezindlela zokufihla Encryptor, emakilasini GIFEncryptorByLSBMethod и GIFEncryptorByPaletteExtensionMethod, kanye nokuqaliswa kokusetshenziswa kubonwa.
Cabangela ikilasi GIFEncryptorByLSBMethod.

Amasimu firstLSBit и secondLSBit ziqukethe izinombolo zamabhithi ebhayithi ngayinye yesithombe lapho umlayezo kufanele ufakwe khona nalapho umlayezo kufanele ufundwe khona. Inkambu checkSequence igcina isheke elilandelanayo ukuze uqinisekise ukubonwa komlayezo oshumekiwe. Indlela emile getEncryptingFileParameters ibuyisela amapharamitha wefayela elishiwo kanye nezici zomlayezo ongaba khona.
Indlela ye-algorithm encrypt class GIFEncryptorByLSBMethod:

Futhi ikhodi yakhe:
@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();
}
I-algorithm kanye nekhodi yomthombo yendlela decrypt class 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);
}
Ukuqaliswa kwekilasi GIFEncryptorByPaletteExtensionMethod zizofana, indlela yokugcina/yokufunda kuphela ehlukile.
Ekilasini MainFrame Izindlela ze-wrapper zichazwe: encryptImage(Encryptor encryptor) и decryptImage(Encryptor encryptor), ukucubungula imiphumela yezindlela zokusebenzelana Encryptor kanye nokusebenzisana nomsebenzisi, okungukuthi ukuvula ibhokisi lokukhetha ifayela, ukubonisa imilayezo yephutha, njll.; kanye nezinye izindlela: openImage(), okuvumela umsebenzisi ukuthi akhethe isithombe, exit(), ephuma kuhlelo lokusebenza. Lezi zindlela zibizwa ngokuthi kusuka Actionizinto zemenyu ezihambisanayo. Leli klasi liphinde lisebenzisa izindlela ezisizayo: createComponents() - ukwakhiwa kwezingxenye zefomu, loadImageFile(File f) — ukulayisha isithombe sibe yinto ekhethekile efayeleni. Ukuqaliswa kwekilasi GIFEncryptorByPaletteExtensionMethod kufana nokuqaliswa kwekilasi GIFEncryptorByLSBMethod, umehluko omkhulu usendleleni amabhayithi omlayezo abhalwa ngayo futhi afundwe kuphalethi.
Ukusebenza kohlelo
Indlela ye-LBS
Ake sithi kunesithombe esinjengalesi:

Kulesi sithombe, iphalethi iqukethe imibala engama-256 (njengoba i-Paint igcina). Imibala emine yokuqala yilena: omhlophe, omnyama, obomvu, oluhlaza okotshani. Eminye imibala emnyama. Ukulandelana kwebhithi yephalethi yomhlaba kuzoba kanjena:
11111111 11111111 11111111 00000000 00000000 00000000 11111111 00000000 00000000 00000000 11111111 00000000...

Uma umlayezo usushumekiwe, amabhithi adwetshelwe azothathelwa indawo amabhithi omlayezo. Isithombe esiwumphumela cishe asihlukile kunesangempela.
Okwangempela
Isithombe esinomlayezo oshumekiwe

![]()
Indlela yokwandisa i-Palette
Uma uvula isithombe esinomlayezo usebenzisa le ndlela, uzobona isithombe esilandelayo:

Kuyacaca ukuthi le ndlela ngeke isebenze emisebenzini yobunhloli egcwele, futhi ingase idinge ukubethelwa okwengeziwe komlayezo.
Ukubethela/ukususa ukubethela ezithombeni ezinyakazayo kusebenza njengasezithombeni ezimile ezivamile, kodwa ukugqwayiza akuphukile.
Imithombo esetshenzisiwe:
Landa:
Source: www.habr.com
