-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathxor_steganography.py
More file actions
102 lines (87 loc) · 3.39 KB
/
xor_steganography.py
File metadata and controls
102 lines (87 loc) · 3.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import numpy as np
class XORSteganography:
def __init__(self):
self.d = {chr(i): i for i in range(256)}
self.c = {i: chr(i) for i in range(256)}
def hide_data(self, image_array, secret_text, encryption_key):
x = np.array(image_array, copy=True)
n, m, z = 0, 0, 0
kl = 0
height, width, channels = x.shape
# Hide length first
length_bytes = len(secret_text).to_bytes(4, byteorder='big')
for byte in length_bytes:
encrypted_byte = byte ^ self.d[encryption_key[kl]]
for bit_pos in range(8):
if n >= height:
raise ValueError("Image too small for the secret text")
bit = (encrypted_byte >> (7 - bit_pos)) & 1
x[n, m, z] = (x[n, m, z] & 0xFE) | bit
z = (z + 1) % 3
if z == 0:
m += 1
if m >= width:
m = 0
n += 1
kl = (kl + 1) % len(encryption_key)
# Hide encrypted text
for char in secret_text:
encrypted_char = self.d[char] ^ self.d[encryption_key[kl]]
for bit_pos in range(8):
if n >= height:
raise ValueError("Image too small for the secret text")
bit = (encrypted_char >> (7 - bit_pos)) & 1
x[n, m, z] = (x[n, m, z] & 0xFE) | bit
z = (z + 1) % 3
if z == 0:
m += 1
if m >= width:
m = 0
n += 1
kl = (kl + 1) % len(encryption_key)
return x
def extract_data(self, image_array, encryption_key):
x = image_array
n, m, z = 0, 0, 0
kl = 0
height, width, channels = x.shape
# Extract length
length_bytes = bytearray()
for _ in range(4):
byte_val = 0
for bit_pos in range(8):
if n >= height:
return "" # No data found
bit = x[n, m, z] & 1
byte_val = (byte_val << 1) | bit
z = (z + 1) % 3
if z == 0:
m += 1
if m >= width:
m = 0
n += 1
decrypted_byte = byte_val ^ self.d[encryption_key[kl]]
length_bytes.append(decrypted_byte)
kl = (kl + 1) % len(encryption_key)
text_length = int.from_bytes(length_bytes, byteorder='big')
# Extract and decrypt text
extracted_text = ""
for _ in range(text_length):
if n >= height:
break
char_val = 0
for bit_pos in range(8):
if n >= height:
break
bit = x[n, m, z] & 1
char_val = (char_val << 1) | bit
z = (z + 1) % 3
if z == 0:
m += 1
if m >= width:
m = 0
n += 1
decrypted_char = self.c[char_val ^ self.d[encryption_key[kl]]]
extracted_text += decrypted_char
kl = (kl + 1) % len(encryption_key)
return extracted_text