Intshayelelo
Imibuliso.
Kungekudala, xa ndandifunda eyunivesithi, kwakukho umsebenzi wekhosi kuqeqesho "Iindlela zeSoftware zokhuseleko lolwazi." Isabelo sasifuna ukuba senze inkqubo efakela umyalezo kwiifayile zeGIF. Ndagqiba ekubeni ndiyenze eJava.
Kule nqaku ndiza kuchaza ezinye iingongoma zethiyori, kunye nendlela le nkqubo encinci yenziwe ngayo.
Inxalenye yethiyori
ifomathi yeGIF
I-GIF (i-Graphics Interchange Format - ifomathi yokutshintshiselana ngemifanekiso) yifomathi yokugcina imifanekiso yegraphic, ekwazi ukugcina idatha ecinezelweyo ngaphandle kokulahlekelwa komgangatho kwifomati ukuya kwi-256 imibala. Le fomati yaphuhliswa ngo-1987 (GIF87a) yiCompuServe yokuhambisa imifanekiso ye-raster kuthungelwano. Kwi-1989, ifomathi yatshintshwa (GIF89a), inkxaso yokungafihli kunye ne-animation yongezwa.
Iifayile ze-GIF zinesakhiwo sebhloko. Ezi bloko zihlala zinobude obumiselweyo (okanye kuxhomekeke kwezinye iiflegi), ngoko ke akunakwenzeka ukuba wenze impazamo malunga nokuba ibhloko nganye ikhona phi. Ubume bowona mfanekiso ulula ongaphiliyo we-GIF kwifomathi ye-GIF89a:

Kuzo zonke iibhloko zesakhiwo, kulo mzekelo siya kuba nomdla kwibhloko ye-palette yehlabathi kunye neeparitha ezijongene nephalethi:
CT- ubukho bephalethi yehlabathi. Ukuba le flegi isetiwe, iphalethi yehlabathi kufuneka iqale ngoko nangoko emva kwesibambo sesikrini esibhadlileyo.Size— ubungakanani bephalethi kunye nenani lemibala emfanekisweni. Amaxabiso ale parameter:
ubungakanani
Inani lemibala
Ubungakanani bePalette, iibhayithi
7
256
768
6
128
384
5
64
192
4
32
96
3
16
48
2
8
24
1
4
12
0
2
6
Iindlela zoguqulelo oluntsonkothileyo
Ezi ndlela zilandelayo ziya kusetyenziswa ukufihla imiyalezo kwiifayile zemifanekiso:
- Indlela ye-LSB (I-Bit encinci eBalulekileyo).
- Indlela yokongeza iPalette
Indlela ye-LSB - indlela eqhelekileyo ye-steganography. Iqulathe ukubuyisela amasuntswana okugqibela abalulekileyo kwisikhongozeli (kwimeko yethu, i-palette bytes yehlabathi) ngamasuntswana omyalezo ofihliweyo.
Inkqubo izakusebenzisa amasuntswana amabini okugqibela kwiibhayithi zephalethi zehlabathi njengenxalenye yale ndlela. Oku kuthetha ukuba kumfanekiso we-24-bit, apho i-palette yombala ingama-byte amathathu obomvu, oluhlaza okwesibhakabhaka, kunye nohlaza, emva kokufaka umyalezo kuwo, icandelo lombala ngalinye liya kutshintsha ngobuninzi be-3/255 gradations. Utshintsho olunjalo, okokuqala, luya kuba lungabonakali okanye lunzima ukuqaphela iliso lomntu, kwaye okwesibini, aluyi kubonakala kwizixhobo zokuvelisa ulwazi oluphantsi.
Ubungakanani bolwazi luya kuxhomekeka ngokuthe ngqo kubungakanani bephalethi yomfanekiso. Ekubeni ubukhulu bobukhulu bephalethi yimibala engama-256, kwaye ukuba iibhithi ezimbini zomyalezo zibhaliwe kwicandelo lombala ngamnye, ngoko ubude bomyalezo ophezulu (kunye nobuninzi bepalethi emfanekisweni) yi-192 bytes. Nje ukuba umyalezo ufakwe kumfanekiso, ubungakanani befayile abutshintshi.
Indlela yokwandiswa kwePalette, esebenza kuphela kwisakhiwo se-GIF. Kuya kuphumelela kakhulu kwimifanekiso ene-palette encinci. Ingundoqo yalo kukuba yandisa ubungakanani be-palette, ngaloo ndlela inika indawo eyongezelelweyo yokubhala ii-bytes eziyimfuneko endaweni ye-bytes yombala. Ukuba sicinga ukuba ubungakanani obuncinci be-palette yimibala emi-2 (i-6 bytes), ngoko ubungakanani obukhulu bomyalezo odibeneyo bunokuba ngu-256 × 3-6 = 762 bytes. Isithintelo kukhuseleko oluphantsi lwe-cryptographic; umyalezo olungisiweyo unokufundwa kusetyenziswa nawuphi na umhleli wokubhaliweyo ukuba umyalezo awufakwanga kuguqulelo oluntsonkothileyo olongezelelweyo.
Inxalenye esebenzayo
Uyilo lwenkqubo
Zonke izixhobo eziyimfuneko zokuphumeza i-encryption kunye ne-decryption algorithms ziya kufakwa kwiphakheji com.tsarik.steganography. Le phakheji ibandakanya ujongano Encryptor ngeendlela encrypt и decrypt, Iklasi Binary, enikezela ukukwazi ukusebenza kunye ne-bit arrays, kunye neeklasi ezingaphandle UnableToEncryptException и UnableToDecryptException, ekufuneka isetyenziswe kwiindlela zojongano Encryptor kwimeko yeempazamo ze-encoding kunye ne-decoding ngokulandelelanayo.
Iphakheji yeprogram engundoqo com.tsarik.programs.gifed izakubandakanya udidi lwenkqubo olubalekayo ngendlela engatshintshiyo main, ikuvumela ukuba usebenzise inkqubo; iklasi egcina iiparamitha zeprogram; kunye neepakethe nezinye iiklasi.
Ukuphunyezwa kwe-algorithms ngokwabo kuya kuboniswa kwiphakheji com.tsarik.programs.gifed.gif iiklasi GIFEncryptorByLSBMethod и GIFEncryptorByPaletteExtensionMethod. Zombini ezi klasi ziya kuphumeza ujongano Encryptor.
Ngokusekwe kubume befomathi yeGIF, unokwenza ialgorithm ngokubanzi yokwazisa umyalezo kwiphalethi yomfanekiso:

Ukumisela ubukho bomyalezo kumfanekiso, kuyimfuneko ukongeza ulandelelwano oluthile lweebhithi ekuqaleni komyalezo, apho i-decoder ifunda kuqala kwaye ihlolisise ukuchaneka. Ukuba ayihambelani, ngoko kuthathwa ukuba akukho myalezo ofihliweyo kumfanekiso. Okulandelayo kufuneka ucacise ubude bomyalezo. Emva koko umbhalo womyalezo ngokwawo.
Umzobo weklasi wesicelo sonke:

Ukuphunyezwa kwenkqubo
Ukuphunyezwa kwenkqubo yonke inokwahlulwa ibe ngamacandelo amabini: ukuphunyezwa kwe-interface encryption kunye neendlela zokucima Encryptor, kwiiklasi GIFEncryptorByLSBMethod и GIFEncryptorByPaletteExtensionMethod, kunye nokuphunyezwa kojongano lomsebenzisi.
Qwalasela iklasi GIFEncryptorByLSBMethod.

amasimi firstLSBit и secondLSBit ziqulathe amanani amasuntswana e-byte nganye yomfanekiso apho umyalezo ungangenwa khona nalapho umyalezo kufuneka ufundwe. Intsimi checkSequence igcina intwana yolandelelwano ukuqinisekisa uqwalaselo lomyalezo olungisiweyo. Indlela engatshintshiyo getEncryptingFileParameters ibuyisela iiparameters zefayile ekhankanyiweyo kunye neempawu zomyalezo onokwenzeka.
Indlela algorithm encrypt класса GIFEncryptorByLSBMethod:

Kwaye ikhowudi yayo:
@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 kunye nekhowudi yomthombo wendlela 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);
}
Ukuphunyezwa kweklasi GIFEncryptorByPaletteExtensionMethod iya kufana, kuphela indlela yokugcina/ukufunda ulwazi eyahlukileyo.
Eklasini MainFrame iindlela zokusonga zichazwe: encryptImage(Encryptor encryptor) и decryptImage(Encryptor encryptor), ukucubungula iziphumo zeendlela zojongano Encryptor kunye nokusebenzisana nomsebenzisi, o.k.t. ukuvula incoko yababini yokukhetha ifayile, ukubonisa imiyalezo yempazamo, njl.; kunye nezinye iindlela: openImage(), ivumela umsebenzisi ukuba akhethe umfanekiso, exit(), ephuma kwisicelo. Ezi ndlela zibizwa ukusuka ActionImiba yemenyu ehambelanayo. Le klasi iphinda isebenzise iindlela ezincedisayo: createComponents() -ukwenziwa kwamacandelo efom, loadImageFile(File f) — ukulayisha umfanekiso kwindawo ekhethekileyo kwifayile. Ukuphunyezwa kweklasi GIFEncryptorByPaletteExtensionMethod iyafana nokuphunyezwa kweklasi GIFEncryptorByLSBMethod, umahluko ophambili ukwindlela i-bytes yomyalezo ebhalwa ngayo kwaye ifundwe kwi-palette.
Ukusebenza kwenkqubo
Indlela ye-LBS
Masithi kukho umfanekiso onje:

Kulo mfanekiso, i-palette iqulethe imibala engama-256 (njengoko iPaint igcina). Imibala emine yokuqala yile: emhlophe, emnyama, ebomvu, eluhlaza. Eminye imibala imnyama. Ulandelelwano lwebit yephalethi yehlabathi luya kuba ngolu hlobo lulandelayo:
11111111 11111111 11111111 00000000 00000000 00000000 11111111 00000000 00000000 00000000 11111111 00000000...

Nje ukuba umyalezo ulungisiwe, amasuntswana akrwelelwe umgca ngaphantsi aya kutshintshwa ngamasuntswana omyalezo. Umfanekiso obangelwayo phantse awufani nowokuqala.
Okwangempela
Umfanekiso onomyalezo ozinzisiweyo

![]()
Indlela yokwandiswa kwePalette
Xa uvula umfanekiso oqulethe umyalezo usebenzisa le ndlela, uya kubona lo mfanekiso ulandelayo:

Kucacile ukuba le ndlela ayiyi kusebenza kwimisebenzi yobuntlola epheleleyo, kwaye inokufuna uguqulelo oluntsonkothileyo lomyalezo.
Uguqulelo oluntsonkothileyo/uguqulelo oluntsonkothileyo kwimifanekiso eshukumayo lusebenza njengemifanekiso esisigxina eqhelekileyo, kodwa oopopayi abophukanga.
Imithombo esetyenzisiweyo:
Khuphela:
umthombo: www.habr.com
