БтСганография Π² GIF

въвСдСниС

ΠŸΠΎΠ·Π΄Ρ€Π°Π²ΠΈ.
НС Ρ‚ΠΎΠ»ΠΊΠΎΠ²Π° ΠΎΡ‚Π΄Π°Π²Π½Π°, ΠΊΠΎΠ³Π°Ρ‚ΠΎ ΡƒΡ‡Π΅Ρ… Π² унивСрситСта, имашС курсова Ρ€Π°Π±ΠΎΡ‚Π° ΠΏΠΎ дисциплината β€žΠ‘ΠΎΡ„Ρ‚ΡƒΠ΅Ρ€Π½ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈ Π·Π° ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΎΠ½Π½Π° ΡΠΈΠ³ΡƒΡ€Π½ΠΎΡΡ‚β€œ. Π—Π°Π΄Π°Π½ΠΈΠ΅Ρ‚ΠΎ изисквашС Π΄Π° създадСм ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°, която Π²Π³Ρ€Π°ΠΆΠ΄Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ Π² GIF Ρ„Π°ΠΉΠ»ΠΎΠ²Π΅. Π Π΅ΡˆΠΈΡ… Π΄Π° Π³ΠΎ направя Π² Java.

Π’ Ρ‚Π°Π·ΠΈ статия Ρ‰Π΅ опиша някои Ρ‚Π΅ΠΎΡ€Π΅Ρ‚ΠΈΡ‡Π½ΠΈ Ρ‚ΠΎΡ‡ΠΊΠΈ, ΠΊΠ°ΠΊΡ‚ΠΎ ΠΈ ΠΊΠ°ΠΊ Π΅ създадСна Ρ‚Π°Π·ΠΈ ΠΌΠ°Π»ΠΊΠ° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°.

Π’Π΅ΠΎΡ€Π΅Ρ‚ΠΈΡ‡Π½Π° част

GIF Ρ„ΠΎΡ€ΠΌΠ°Ρ‚

GIF (Graphics Interchange Format - Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ Π·Π° ΠΎΠ±ΠΌΠ΅Π½ Π½Π° изобраТСния) Π΅ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ Π·Π° ΡΡŠΡ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅ Π½Π° Π³Ρ€Π°Ρ„ΠΈΡ‡Π½ΠΈ изобраТСния, способСн Π΄Π° ΡΡŠΡ…Ρ€Π°Π½ΡΠ²Π° компрСсирани Π΄Π°Π½Π½ΠΈ Π±Π΅Π· Π·Π°Π³ΡƒΠ±Π° Π½Π° качСство във Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ Π΄ΠΎ 256 цвята. Π’ΠΎΠ·ΠΈ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ Π΅ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π΅Π½ ΠΏΡ€Π΅Π· 1987 Π³. (GIF87a) ΠΎΡ‚ CompuServe Π·Π° ΠΏΡ€Π΅Π΄Π°Π²Π°Π½Π΅ Π½Π° растСрни изобраТСния ΠΏΠΎ ΠΌΡ€Π΅ΠΆΠΈ. ΠŸΡ€Π΅Π· 1989 Π³. Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΡŠΡ‚ Π΅ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€Π°Π½ (GIF89a), Π΄ΠΎΠ±Π°Π²Π΅Π½Π° Π΅ ΠΏΠΎΠ΄Π΄Ρ€ΡŠΠΆΠΊΠ° Π·Π° прозрачност ΠΈ анимация.

GIF Ρ„Π°ΠΉΠ»ΠΎΠ²Π΅Ρ‚Π΅ ΠΈΠΌΠ°Ρ‚ Π±Π»ΠΎΠΊΠΎΠ²Π° структура. Π’Π΅Π·ΠΈ Π±Π»ΠΎΠΊΠΎΠ²Π΅ Π²ΠΈΠ½Π°Π³ΠΈ ΠΈΠΌΠ°Ρ‚ фиксирана дълТина (ΠΈΠ»ΠΈ Ρ‚ΠΎΠ²Π° зависи ΠΎΡ‚ някои Ρ„Π»Π°Π³ΠΎΠ²Π΅), Ρ‚Π°ΠΊΠ° Ρ‡Π΅ Π΅ ΠΏΠΎΡ‡Ρ‚ΠΈ нСвъзмоТно Π΄Π° сС Π½Π°ΠΏΡ€Π°Π²ΠΈ Π³Ρ€Π΅ΡˆΠΊΠ° къдС сС Π½Π°ΠΌΠΈΡ€Π° всСки Π±Π»ΠΎΠΊ. Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π°Ρ‚Π° Π½Π° Π½Π°ΠΉ-простото Π½Π΅Π°Π½ΠΈΠΌΠΈΡ€Π°Π½ΠΎ GIF ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ във Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ GIF89a:

БтСганография Π² 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 (Π½Π°ΠΉ-малък Π·Π½Π°Ρ‡ΠΈΠΌ Π±ΠΈΡ‚).
  • ΠœΠ΅Ρ‚ΠΎΠ΄ Π·Π° добавянС Π½Π° ΠΏΠ°Π»ΠΈΡ‚Ρ€ΠΈ

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, основната Ρ€Π°Π·Π»ΠΈΠΊΠ° Π΅ Π² Π½Π°Ρ‡ΠΈΠ½Π°, ΠΏΠΎ ΠΊΠΎΠΉΡ‚ΠΎ Π±Π°ΠΉΡ‚ΠΎΠ²Π΅Ρ‚Π΅ Π½Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡΡ‚Π° сС записват ΠΈ Ρ‡Π΅Ρ‚Π°Ρ‚ ΠΎΡ‚ ΠΏΠ°Π»ΠΈΡ‚Ρ€Π°Ρ‚Π°.

Π Π°Π±ΠΎΡ‚Π° Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π°

LBS ΠΌΠ΅Ρ‚ΠΎΠ΄

Π”Π° ΠΊΠ°ΠΆΠ΅ΠΌ, Ρ‡Π΅ ΠΈΠΌΠ° ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΠΊΠ°Ρ‚ΠΎ Ρ‚ΠΎΠ²Π°:

БтСганография Π² GIF

Π’ Ρ‚ΠΎΠ²Π° ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΠΏΠ°Π»ΠΈΡ‚Ρ€Π°Ρ‚Π° сС ΡΡŠΡΡ‚ΠΎΠΈ ΠΎΡ‚ 256 цвята (ΠΊΠ°ΠΊΡ‚ΠΎ Paint Π·Π°ΠΏΠ°Π·Π²Π°). ΠŸΡŠΡ€Π²ΠΈΡ‚Π΅ Ρ‡Π΅Ρ‚ΠΈΡ€ΠΈ цвята са: бяло, Ρ‡Π΅Ρ€Π½ΠΎ, Ρ‡Π΅Ρ€Π²Π΅Π½ΠΎ, Π·Π΅Π»Π΅Π½ΠΎ. Π”Ρ€ΡƒΠ³ΠΈΡ‚Π΅ Ρ†Π²Π΅Ρ‚ΠΎΠ²Π΅ са Ρ‡Π΅Ρ€Π½ΠΈ. Π“Π»ΠΎΠ±Π°Π»Π½Π°Ρ‚Π° Π±ΠΈΡ‚ΠΎΠ²Π° послСдоватСлност Π½Π° ΠΏΠ°Π»ΠΈΡ‚Ρ€Π°Ρ‚Π° Ρ‰Π΅ бъдС ΠΊΠ°ΠΊΡ‚ΠΎ слСдва:

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

БтСганография Π² GIF

Π‘Π»Π΅Π΄ ΠΊΠ°Ρ‚ΠΎ ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅Ρ‚ΠΎ бъдС Π²Π³Ρ€Π°Π΄Π΅Π½ΠΎ, ΠΏΠΎΠ΄Ρ‡Π΅Ρ€Ρ‚Π°Π½ΠΈΡ‚Π΅ Π±ΠΈΡ‚ΠΎΠ²Π΅ Ρ‰Π΅ Π±ΡŠΠ΄Π°Ρ‚ Π·Π°ΠΌΠ΅Π½Π΅Π½ΠΈ с Π±ΠΈΡ‚ΠΎΠ²Π΅Ρ‚Π΅ ΠΎΡ‚ ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅Ρ‚ΠΎ. ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΎΡ‚ΠΎ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΠΏΠΎΡ‡Ρ‚ΠΈ Π½Π΅ сС Ρ€Π°Π·Π»ΠΈΡ‡Π°Π²Π° ΠΎΡ‚ ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»Π°.

ΠžΡ€ΠΈΠ³ΠΈΠ½Π°Π»
Π˜Π·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ с Π²Π³Ρ€Π°Π΄Π΅Π½ΠΎ ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅

БтСганография Π² GIF
БтСганография Π² GIF

ΠœΠ΅Ρ‚ΠΎΠ΄ Π·Π° Ρ€Π°Π·ΡˆΠΈΡ€ΡΠ²Π°Π½Π΅ Π½Π° ΠΏΠ°Π»ΠΈΡ‚Ρ€Π°Ρ‚Π°

ΠšΠΎΠ³Π°Ρ‚ΠΎ ΠΎΡ‚Π²ΠΎΡ€ΠΈΡ‚Π΅ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅, ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Ρ‰ΠΎ ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ Ρ‚ΠΎΠ·ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄, Ρ‰Π΅ Π²ΠΈΠ΄ΠΈΡ‚Π΅ слСдната ΠΊΠ°Ρ€Ρ‚ΠΈΠ½Π°:

БтСганография Π² GIF

Ясно Π΅, Ρ‡Π΅ Ρ‚ΠΎΠ·ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ няма Π΄Π° Ρ€Π°Π±ΠΎΡ‚ΠΈ Π·Π° ΠΏΡŠΠ»Π½ΠΎΡ†Π΅Π½Π½ΠΈ шпионски дСйности ΠΈ ΠΌΠΎΠΆΠ΅ Π΄Π° изисква Π΄ΠΎΠΏΡŠΠ»Π½ΠΈΡ‚Π΅Π»Π½ΠΎ ΠΊΡ€ΠΈΠΏΡ‚ΠΈΡ€Π°Π½Π΅ Π½Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅Ρ‚ΠΎ.

Π¨ΠΈΡ„Ρ€ΠΎΠ²Π°Π½Π΅Ρ‚ΠΎ/Π΄Π΅ΠΊΡ€ΠΈΠΏΡ‚ΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ Π² Π°Π½ΠΈΠΌΠΈΡ€Π°Π½ΠΈ изобраТСния Ρ€Π°Π±ΠΎΡ‚ΠΈ Ρ‚ΠΎΡ‡Π½ΠΎ ΠΊΠ°ΠΊΡ‚ΠΎ Π² ΠΎΠ±ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΈ статични изобраТСния, Π½ΠΎ анимацията Π½Π΅ сС разваля.

Използвани ΠΈΠ·Ρ‚ΠΎΡ‡Π½ΠΈΡ†ΠΈ:

изтСглянС:

Π˜Π·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ: www.habr.com

ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС с DDoS Π·Π°Ρ‰ΠΈΡ‚Π°, VPS VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ πŸ”₯ ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ ΡƒΠ΅Π± хостинг със Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS Π°Ρ‚Π°ΠΊΠΈ, VPS VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ | ProHoster