GIF ನಲ್ಲಿ ಸ್ಟೆಗಾನೋಗ್ರಫಿ

ಪರಿಚಯ

ಶುಭಾಶಯಗಳು.
ಬಹಳ ಹಿಂದೆಯೇ, ನಾನು ವಿಶ್ವವಿದ್ಯಾನಿಲಯದಲ್ಲಿ ಓದುತ್ತಿದ್ದಾಗ, "ಮಾಹಿತಿ ಸುರಕ್ಷತೆಯ ಸಾಫ್ಟ್‌ವೇರ್ ವಿಧಾನಗಳು" ವಿಭಾಗದಲ್ಲಿ ಕೋರ್ಸ್‌ವರ್ಕ್ ಇತ್ತು. ನಿಯೋಜನೆಯು GIF ಫೈಲ್‌ಗಳಲ್ಲಿ ಸಂದೇಶವನ್ನು ಎಂಬೆಡ್ ಮಾಡುವ ಪ್ರೋಗ್ರಾಂ ಅನ್ನು ರಚಿಸುವ ಅಗತ್ಯವಿದೆ. ನಾನು ಅದನ್ನು ಜಾವಾದಲ್ಲಿ ಮಾಡಲು ನಿರ್ಧರಿಸಿದೆ.

ಈ ಲೇಖನದಲ್ಲಿ ನಾನು ಕೆಲವು ಸೈದ್ಧಾಂತಿಕ ಅಂಶಗಳನ್ನು ವಿವರಿಸುತ್ತೇನೆ, ಹಾಗೆಯೇ ಈ ಸಣ್ಣ ಪ್ರೋಗ್ರಾಂ ಅನ್ನು ಹೇಗೆ ರಚಿಸಲಾಗಿದೆ.

ಸೈದ್ಧಾಂತಿಕ ಭಾಗ

GIF ಸ್ವರೂಪ

GIF (ಗ್ರಾಫಿಕ್ಸ್ ಇಂಟರ್‌ಚೇಂಜ್ ಫಾರ್ಮ್ಯಾಟ್ - ಚಿತ್ರಗಳನ್ನು ವಿನಿಮಯ ಮಾಡಿಕೊಳ್ಳುವ ಸ್ವರೂಪ) ಗ್ರಾಫಿಕ್ ಚಿತ್ರಗಳನ್ನು ಸಂಗ್ರಹಿಸಲು ಒಂದು ಸ್ವರೂಪವಾಗಿದೆ, ಇದು 256 ಬಣ್ಣಗಳ ಸ್ವರೂಪದಲ್ಲಿ ಗುಣಮಟ್ಟವನ್ನು ಕಳೆದುಕೊಳ್ಳದೆ ಸಂಕುಚಿತ ಡೇಟಾವನ್ನು ಸಂಗ್ರಹಿಸುವ ಸಾಮರ್ಥ್ಯವನ್ನು ಹೊಂದಿದೆ. ಈ ಸ್ವರೂಪವನ್ನು 1987 ರಲ್ಲಿ (GIF87a) ನೆಟ್‌ವರ್ಕ್‌ಗಳ ಮೂಲಕ ರಾಸ್ಟರ್ ಚಿತ್ರಗಳನ್ನು ರವಾನಿಸಲು CompuServe ನಿಂದ ಅಭಿವೃದ್ಧಿಪಡಿಸಲಾಯಿತು. 1989 ರಲ್ಲಿ, ಸ್ವರೂಪವನ್ನು ಮಾರ್ಪಡಿಸಲಾಯಿತು (GIF89a), ಪಾರದರ್ಶಕತೆ ಮತ್ತು ಅನಿಮೇಷನ್‌ಗೆ ಬೆಂಬಲವನ್ನು ಸೇರಿಸಲಾಯಿತು.

GIF ಫೈಲ್‌ಗಳು ಬ್ಲಾಕ್ ರಚನೆಯನ್ನು ಹೊಂದಿವೆ. ಈ ಬ್ಲಾಕ್‌ಗಳು ಯಾವಾಗಲೂ ಸ್ಥಿರ ಉದ್ದವನ್ನು ಹೊಂದಿರುತ್ತವೆ (ಅಥವಾ ಇದು ಕೆಲವು ಧ್ವಜಗಳ ಮೇಲೆ ಅವಲಂಬಿತವಾಗಿರುತ್ತದೆ), ಆದ್ದರಿಂದ ಪ್ರತಿ ಬ್ಲಾಕ್ ಎಲ್ಲಿದೆ ಎಂಬುದರ ಬಗ್ಗೆ ತಪ್ಪು ಮಾಡುವುದು ಅಸಾಧ್ಯ. GIF89a ಫಾರ್ಮ್ಯಾಟ್‌ನಲ್ಲಿ ಸರಳವಾದ ಅನಿಮೇಟೆಡ್ ಅಲ್ಲದ GIF ಚಿತ್ರದ ರಚನೆ:

GIF ನಲ್ಲಿ ಸ್ಟೆಗಾನೋಗ್ರಫಿ

ರಚನೆಯ ಎಲ್ಲಾ ಬ್ಲಾಕ್‌ಗಳಲ್ಲಿ, ಈ ಸಂದರ್ಭದಲ್ಲಿ ನಾವು ಜಾಗತಿಕ ಪ್ಯಾಲೆಟ್ ಬ್ಲಾಕ್ ಮತ್ತು ಪ್ಯಾಲೆಟ್‌ಗೆ ಜವಾಬ್ದಾರರಾಗಿರುವ ನಿಯತಾಂಕಗಳಲ್ಲಿ ಆಸಕ್ತಿ ಹೊಂದಿರುತ್ತೇವೆ:

  • 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 (ಕಡಿಮೆ ಮಹತ್ವದ ಬಿಟ್) ವಿಧಾನ
  • ಪ್ಯಾಲೆಟ್ ಸೇರ್ಪಡೆ ವಿಧಾನ

ಎಲ್ಎಸ್ಬಿ ವಿಧಾನ - ಸ್ಟೆಗಾನೋಗ್ರಫಿಯ ಸಾಮಾನ್ಯ ವಿಧಾನ. ಇದು ಧಾರಕದಲ್ಲಿನ ಕೊನೆಯ ಗಮನಾರ್ಹ ಬಿಟ್‌ಗಳನ್ನು (ನಮ್ಮ ಸಂದರ್ಭದಲ್ಲಿ, ಜಾಗತಿಕ ಪ್ಯಾಲೆಟ್ ಬೈಟ್‌ಗಳು) ಗುಪ್ತ ಸಂದೇಶದ ಬಿಟ್‌ಗಳೊಂದಿಗೆ ಬದಲಾಯಿಸುವುದನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ.

ಪ್ರೋಗ್ರಾಂ ಈ ವಿಧಾನದ ಭಾಗವಾಗಿ ಜಾಗತಿಕ ಪ್ಯಾಲೆಟ್ ಬೈಟ್‌ಗಳಲ್ಲಿ ಕೊನೆಯ ಎರಡು ಬಿಟ್‌ಗಳನ್ನು ಬಳಸುತ್ತದೆ. ಇದರರ್ಥ 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 ಸ್ವರೂಪದ ರಚನೆಯ ಆಧಾರದ ಮೇಲೆ, ಇಮೇಜ್ ಪ್ಯಾಲೆಟ್‌ಗೆ ಸಂದೇಶವನ್ನು ಪರಿಚಯಿಸಲು ನೀವು ಸಾಮಾನ್ಯ ಅಲ್ಗಾರಿದಮ್ ಅನ್ನು ರಚಿಸಬಹುದು:

GIF ನಲ್ಲಿ ಸ್ಟೆಗಾನೋಗ್ರಫಿ

ಚಿತ್ರದಲ್ಲಿ ಸಂದೇಶದ ಉಪಸ್ಥಿತಿಯನ್ನು ನಿರ್ಧರಿಸಲು, ಸಂದೇಶದ ಪ್ರಾರಂಭಕ್ಕೆ ಬಿಟ್‌ಗಳ ನಿರ್ದಿಷ್ಟ ಅನುಕ್ರಮವನ್ನು ಸೇರಿಸುವುದು ಅವಶ್ಯಕ, ಅದನ್ನು ಡಿಕೋಡರ್ ಮೊದಲು ಓದುತ್ತದೆ ಮತ್ತು ಸರಿಯಾಗಿದೆಯೇ ಎಂದು ಪರಿಶೀಲಿಸುತ್ತದೆ. ಅದು ಹೊಂದಿಕೆಯಾಗದಿದ್ದರೆ, ಚಿತ್ರದಲ್ಲಿ ಯಾವುದೇ ಗುಪ್ತ ಸಂದೇಶವಿಲ್ಲ ಎಂದು ಪರಿಗಣಿಸಲಾಗುತ್ತದೆ. ಮುಂದೆ ನೀವು ಸಂದೇಶದ ಉದ್ದವನ್ನು ನಿರ್ದಿಷ್ಟಪಡಿಸಬೇಕಾಗಿದೆ. ನಂತರ ಸಂದೇಶದ ಪಠ್ಯ ಸ್ವತಃ.

ಸಂಪೂರ್ಣ ಅಪ್ಲಿಕೇಶನ್‌ನ ವರ್ಗ ರೇಖಾಚಿತ್ರ:

GIF ನಲ್ಲಿ ಸ್ಟೆಗಾನೋಗ್ರಫಿ

ಕಾರ್ಯಕ್ರಮದ ಅನುಷ್ಠಾನ

ಸಂಪೂರ್ಣ ಪ್ರೋಗ್ರಾಂನ ಅನುಷ್ಠಾನವನ್ನು ಎರಡು ಘಟಕಗಳಾಗಿ ವಿಂಗಡಿಸಬಹುದು: ಇಂಟರ್ಫೇಸ್ ಎನ್ಕ್ರಿಪ್ಶನ್ ಮತ್ತು ಡೀಕ್ರಿಪ್ಶನ್ ವಿಧಾನಗಳ ಅನುಷ್ಠಾನ Encryptor, ತರಗತಿಗಳಲ್ಲಿ GIFEncryptorByLSBMethod и GIFEncryptorByPaletteExtensionMethod, ಮತ್ತು ಬಳಕೆದಾರ ಇಂಟರ್ಫೇಸ್ನ ಅನುಷ್ಠಾನ.

ವರ್ಗವನ್ನು ಪರಿಗಣಿಸಿ GIFEncryptorByLSBMethod.

GIF ನಲ್ಲಿ ಸ್ಟೆಗಾನೋಗ್ರಫಿ

ಕ್ಷೇತ್ರಗಳು firstLSBit и secondLSBit ಸಂದೇಶವನ್ನು ನಮೂದಿಸಬೇಕಾದ ಚಿತ್ರದ ಪ್ರತಿ ಬೈಟ್‌ನ ಬಿಟ್‌ಗಳ ಸಂಖ್ಯೆಯನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ ಮತ್ತು ಸಂದೇಶವನ್ನು ಎಲ್ಲಿ ಓದಬೇಕು. ಕ್ಷೇತ್ರ checkSequence ಎಂಬೆಡೆಡ್ ಸಂದೇಶದ ಗುರುತಿಸುವಿಕೆಯನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಲು ಚೆಕ್ ಬಿಟ್ ಅನುಕ್ರಮವನ್ನು ಸಂಗ್ರಹಿಸುತ್ತದೆ. ಸ್ಥಾಯೀ ವಿಧಾನ getEncryptingFileParameters ನಿರ್ದಿಷ್ಟಪಡಿಸಿದ ಫೈಲ್‌ನ ನಿಯತಾಂಕಗಳನ್ನು ಮತ್ತು ಸಂಭಾವ್ಯ ಸಂದೇಶದ ಗುಣಲಕ್ಷಣಗಳನ್ನು ಹಿಂತಿರುಗಿಸುತ್ತದೆ.

ವಿಧಾನ ಅಲ್ಗಾರಿದಮ್ encrypt ವರ್ಗ GIFEncryptorByLSBMethod:

GIF ನಲ್ಲಿ ಸ್ಟೆಗಾನೋಗ್ರಫಿ

ಮತ್ತು ಅವನ ಕೋಡ್:

@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:

GIF ನಲ್ಲಿ ಸ್ಟೆಗಾನೋಗ್ರಫಿ

@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, ಮುಖ್ಯ ವ್ಯತ್ಯಾಸವೆಂದರೆ ಸಂದೇಶ ಬೈಟ್‌ಗಳನ್ನು ಪ್ಯಾಲೆಟ್‌ನಿಂದ ಬರೆಯುವ ಮತ್ತು ಓದುವ ವಿಧಾನದಲ್ಲಿ.

ಕಾರ್ಯಕ್ರಮದ ಕಾರ್ಯಾಚರಣೆ

ಎಲ್ಬಿಎಸ್ ವಿಧಾನ

ಈ ರೀತಿಯ ಚಿತ್ರವಿದೆ ಎಂದು ಹೇಳೋಣ:

GIF ನಲ್ಲಿ ಸ್ಟೆಗಾನೋಗ್ರಫಿ

ಈ ಚಿತ್ರದಲ್ಲಿ, ಪ್ಯಾಲೆಟ್ 256 ಬಣ್ಣಗಳನ್ನು ಒಳಗೊಂಡಿದೆ (ಪೇಂಟ್ ಉಳಿಸಿದಂತೆ). ಮೊದಲ ನಾಲ್ಕು ಬಣ್ಣಗಳು: ಬಿಳಿ, ಕಪ್ಪು, ಕೆಂಪು, ಹಸಿರು. ಇತರ ಬಣ್ಣಗಳು ಕಪ್ಪು. ಜಾಗತಿಕ ಪ್ಯಾಲೆಟ್ ಬಿಟ್ ಅನುಕ್ರಮವು ಈ ಕೆಳಗಿನಂತಿರುತ್ತದೆ:

11111111 11111111 11111111 00000000 00000000 00000000 11111111 00000000 00000000 00000000 11111111 00000000...

GIF ನಲ್ಲಿ ಸ್ಟೆಗಾನೋಗ್ರಫಿ

ಸಂದೇಶವನ್ನು ಎಂಬೆಡ್ ಮಾಡಿದ ನಂತರ, ಅಂಡರ್‌ಲೈನ್ ಮಾಡಿದ ಬಿಟ್‌ಗಳನ್ನು ಸಂದೇಶದಿಂದ ಬಿಟ್‌ಗಳೊಂದಿಗೆ ಬದಲಾಯಿಸಲಾಗುತ್ತದೆ. ಪರಿಣಾಮವಾಗಿ ಚಿತ್ರವು ಮೂಲದಿಂದ ಬಹುತೇಕ ಭಿನ್ನವಾಗಿರುವುದಿಲ್ಲ.

ಮೂಲ
ಎಂಬೆಡೆಡ್ ಸಂದೇಶದೊಂದಿಗೆ ಚಿತ್ರ

GIF ನಲ್ಲಿ ಸ್ಟೆಗಾನೋಗ್ರಫಿ
GIF ನಲ್ಲಿ ಸ್ಟೆಗಾನೋಗ್ರಫಿ

ಪ್ಯಾಲೆಟ್ ವಿಸ್ತರಣೆ ವಿಧಾನ

ಈ ವಿಧಾನವನ್ನು ಬಳಸಿಕೊಂಡು ಸಂದೇಶವನ್ನು ಹೊಂದಿರುವ ಚಿತ್ರವನ್ನು ನೀವು ತೆರೆದಾಗ, ನೀವು ಈ ಕೆಳಗಿನ ಚಿತ್ರವನ್ನು ನೋಡುತ್ತೀರಿ:

GIF ನಲ್ಲಿ ಸ್ಟೆಗಾನೋಗ್ರಫಿ

ಪೂರ್ಣ ಪ್ರಮಾಣದ ಬೇಹುಗಾರಿಕೆ ಚಟುವಟಿಕೆಗಳಿಗೆ ಈ ವಿಧಾನವು ಕಾರ್ಯನಿರ್ವಹಿಸುವುದಿಲ್ಲ ಎಂಬುದು ಸ್ಪಷ್ಟವಾಗಿದೆ ಮತ್ತು ಸಂದೇಶದ ಹೆಚ್ಚುವರಿ ಎನ್‌ಕ್ರಿಪ್ಶನ್ ಅಗತ್ಯವಿರಬಹುದು.

ಅನಿಮೇಟೆಡ್ ಚಿತ್ರಗಳಲ್ಲಿನ ಎನ್‌ಕ್ರಿಪ್ಶನ್/ಡಿಕ್ರಿಪ್ಶನ್ ಸಾಮಾನ್ಯ ಸ್ಥಿರ ಚಿತ್ರಗಳಂತೆಯೇ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ, ಆದರೆ ಅನಿಮೇಷನ್ ಮುರಿದುಹೋಗಿಲ್ಲ.

ಬಳಸಿದ ಮೂಲಗಳು:

ಡೌನ್‌ಲೋಡ್ ಮಾಡಿ:

ಮೂಲ: www.habr.com

ಕಾಮೆಂಟ್ ಅನ್ನು ಸೇರಿಸಿ