salaan.
Muddo aan sidaas u fogayn, markii aan jaamacadda wax ka baranayay, waxaa jiray shaqo koorso ah oo ku saabsan edbinta “Hababka Software-ka ee amniga macluumaadka.” Hawshu waxay nooga baahnayd inaanu abuurno barnaamij fariinta ku dhex jira faylasha GIF. Waxaan go'aansaday inaan ku sameeyo Java.
Maqaalkan waxaan ku tilmaami doonaa qaar ka mid ah qodobbada aragtida, iyo sidoo kale sida barnaamijkan yar loo abuuray.
Qaybta aragtida
Qaab GIF
GIF (Qaabka Isweydaarsiga Garaafyada - qaab lagu kala beddelo sawirada) waa qaab lagu kaydiyo sawirrada garaafyada, awood u leh in lagu kaydiyo xogta la cufan iyada oo aan la lumin tayada qaab ilaa 256 midab ah. Qaabkan waxa la sameeyay 1987 (GIF87a) CompuServe si loogu gudbiyo sawirada rasterka ee shabakadaha. 1989kii, qaabka waa la bedelay (GIF89a), taageerada daahfurnaanta iyo animation ayaa lagu daray.
Faylasha GIF waxay leeyihiin qaab dhismeed. Baloogyadani had iyo jeer waxay leeyihiin dherer go'an (ama waxay kuxirantahay calanka qaarkood), sidaa darteed waa wax aan macquul aheyn in qalad laga sameeyo meesha block kasta uu ku yaal. Qaab dhismeedka sawirka GIF ee ugu fudud ee aan firfircoonayn ee qaabka GIF89a:
Dhammaan baloogyada qaab-dhismeedka, kiiskan waxaan xiisayn doonaa xannibaadda palette ee caalamiga ah iyo xuduudaha mas'uulka ka ah palette:
Hababka soo socda ayaa loo isticmaali doonaa si loo sireeyo fariimaha ku jira faylasha sawirka:
Habka LSB (Birta ugu Muhiimsan).
Habka isku-darka palette
Habka LSB - habka caadiga ah ee steganography. Waxay ka kooban tahay beddelidda qaybihii muhiimka ahaa ee ugu dambeeyay weelka (xaaladkeenna, baytyada palette-yada caalamiga ah) oo lagu beddelo qaybo ka mid ah farriinta qarsoon.
Barnaamijku waxa uu isticmaali doonaa labada bit ee ugu dambeeya ee palette bytes-ka caalamiga ah iyada oo qayb ka ah habkan. Tani waxay ka dhigan tahay in sawirka 24-bit, halkaasoo midabka palette uu yahay saddex bytes oo casaan, buluug, iyo cagaar ah, ka dib marka la dhexgeliyo fariinta, qayb kasta oo midab ah ayaa isbeddeli doonta ugu badnaan 3/255 darajo. Isbeddelka noocan oo kale ah, marka hore, wuxuu noqon doonaa mid aan la arki karin ama ay adag tahay in la dareemo indhaha bini'aadamka, marka labaad, ma muuqan doonto qalabka wax soo saarka macluumaadka tayada hooseeya.
Qadarka macluumaadka ayaa si toos ah ugu xirnaan doona xajmiga palette sawirka. Maadaama cabbirka ugu badan ee palette uu yahay 256 midab, iyo haddii laba xabbadood oo farriin ah lagu qoro qaybta midab kasta, markaa dhererka farriinta ugu badan (oo leh palette ugu badan ee sawirka) waa 192 bytes. Marka farriinta lagu dhejiyo sawirka, cabbirka feylku isma beddelayo.
Habka ballaarinta palette, kaas oo kaliya u shaqeeya qaab dhismeedka GIF. Waxay noqon doontaa ugu waxtarka badan sawirada leh palette yar. Nuxurkeedu waa in ay kordhiso xajmiga palette-ka, taas oo bixisa meel dheeraad ah oo loogu talagalay qorista bytes lagama maarmaanka ah ee goobta midabka midabka. Haddii aan tixgelinno in cabbirka ugu yar ee palette uu yahay 2 midab (6 bytes), markaa cabbirka ugu sarreeya ee farriinta ku xiran waxay noqon kartaa 256 × 3-6 = 762 bytes. Khasaaradu waa badbaado qarsoodi ah oo hooseeya; fariinta ku duugan waa la akhrin karaa iyadoo la adeegsanayo tifaftire kasta oo qoraal ah haddii fariinta aan lagu hoos gelin sirin dheeri ah.
Qayb la taaban karo
Naqshadeynta barnaamijka
Dhammaan qalabka lagama maarmaanka u ah hirgelinta sirta iyo algorithms-ka-dejinta ayaa lagu dari doonaa xirmada com.tsarik.steganography. Xirmadan waxaa ku jira interface-ka Encryptor oo leh habab encrypt и decrypt, Fasalka Binary, kaas oo bixiya awoodda lagu shaqeynayo qaybo yaryar, iyo sidoo kale fasallo ka reeban UnableToEncryptException и UnableToDecryptException, kaas oo ay tahay in loo isticmaalo hababka interface Encryptor haddii ay dhacdo in codaynta iyo dejinta khaladaadka siday u kala horreeyaan.
Hirgelinta algorithms laftooda ayaa lagu soo bandhigi doonaa xirmada com.tsarik.programs.gifed.gif fasallada GIFEncryptorByLSBMethod и GIFEncryptorByPaletteExtensionMethod. Labadan fasalba waxay hirgelin doonaan interface-ka Encryptor.
Iyada oo ku saleysan qaab dhismeedka qaabka GIF, waxaad abuuri kartaa algorithm guud si aad fariin ugu gudbiso palette sawirka:
Si loo go'aamiyo joogitaanka fariinta sawirka, waxaa lagama maarmaan ah in lagu daro taxane gaar ah oo xariijimo ah bilowga fariinta, kaas oo decoder-ku marka hore akhriyo oo hubiyo saxnaanta. Haddii aysan u dhigmin, markaa waxaa loo tixgeliyaa in aysan jirin fariin qarsoon oo sawirka ah. Marka xigta waxaad u baahan tahay inaad sheegto dhererka fariinta. Kadib qoraalka fariinta lafteeda.
Jaantuska fasalka ee codsiga oo dhan:
Hirgelinta barnaamijka
Hirgelinta barnaamijka oo dhan waxaa loo qaybin karaa laba qaybood: hirgelinta encryption interface iyo hababka decryption Encryptor, fasallada GIFEncryptorByLSBMethod и GIFEncryptorByPaletteExtensionMethod, iyo hirgelinta interface interface.
Tixgeli fasalka GIFEncryptorByLSBMethod.
beeraha firstLSBit и secondLSBit waxa ku jira nambarada bayt kasta oo sawirka ka mid ah kaas oo fariinta la gelinayo iyo meesha ay tahay in fariinta laga akhriyo. Garoonka checkSequence kaydiyaa jeeg isku xigxiga si loo hubiyo aqoonsiga fariinta guntan. Habka taagan getEncryptingFileParameters soo celisa xuduudaha faylka la cayimay iyo sifooyinka fariinta suurtagalka ah.
@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();
}
Algorithm iyo isha code ee habka decrypt fasalka 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);
}
Hirgelinta fasalka GIFEncryptorByPaletteExtensionMethod waxay la mid noqon doontaa, kaliya habka kaydinta/akhrinta macluumaadka ayaa ka duwan.
Fasalka dhexdiisa MainFrame hababka duubista ayaa lagu sifeeyay: encryptImage(Encryptor encryptor) и decryptImage(Encryptor encryptor), farsamaynta natiijooyinka hababka interface Encryptor iyo la falgalka isticmaalaha, tusaale ahaan furitaanka wada-hadalka xulashada faylka, muujinta farriimaha khaldan, iwm.; iyo sidoo kale habab kale: openImage(), u oggolaanaya isticmaalaha inuu doorto sawir, exit(), kaas oo ka baxa codsiga. Hababkaan waxaa loo yaqaan Actionalaabta menu ee u dhigma. Fasalkani waxa kale oo uu fuliyaa habab caawimo: createComponents() - abuurista qaybaha qaabka, loadImageFile(File f) - ku rarida sawirka qayb gaar ah oo ka mid ah faylka. Hirgelinta fasalka GIFEncryptorByPaletteExtensionMethod oo la mid ah hirgelinta fasalka GIFEncryptorByLSBMethod, Farqiga ugu weyni waa habka farriimaha loo qoro oo laga akhriyo palette.
Hawlgalka barnaamijka
Habka LBS
Aynu nidhaahno waxaa jira sawir sidan oo kale ah:
Sawirkan, palette-ku wuxuu ka kooban yahay 256 midab (sida Rinjiga u kaydiyo). Afarta midab ee hore waa: caddaan, madow, casaan, cagaar. Midabada kale waa madow. Isku xigxiga xoogaa palette ee caalamiga ah wuxuu noqon doonaa sida soo socota:
Marka fariinta la dhex dhigo, xariiqyada hoosta laga xarriiqay waxaa lagu bedelayaa qaybihii farriinta. Sawirka soo baxay kuma dhowa mid ka duwan kan asalka ah.
Asalka
Sawirka fariinta ku duugan
Habka ballaarinta palette
Marka aad furto sawir ay ku jirto fariin adigoo isticmaalaya habkan, waxaad arki doontaa sawirka soo socda:
Way caddahay in habkani aanu u shaqayn doonin hawlo basaasnimo oo buuxda, oo laga yaabo in uu u baahdo sir dheeraad ah oo fariinta ah.
Sirin/dejinta sawirada firfircooni waxay u shaqeysaa sida sawirada caadiga ah, laakiin animation-ku ma jabna.