-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsteganography.py
171 lines (129 loc) · 5.69 KB
/
steganography.py
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
import cv2
import os
HEADER_FILENAME_LENGTH = 30 # Length of filename to be embedded in image
HEADER_FILESIZE_LENGTH = 20 # Length of filesize to be embedded in image
HEADER_LENGTH = HEADER_FILENAME_LENGTH + HEADER_FILESIZE_LENGTH # Total Header length
# ex : n: 104 ---> [011, 010, 00]
getBits = lambda n : [n>>5 , (n & 0x1C) >>2 , (n & 0x3)] # 0x1C = 00011100
# ex : bits[011, 010, 00] ---> 104
getByte = lambda bits : ((bits[0]<<5)|(bits[1]<<2)|bits[2])
def getFileSize(fileName):
try:
return os.stat(fileName).st_size # Return the size of the file
except:
return 0
def generateHeader(fileName):
qty = getFileSize(fileName)
# fileName = d:/Myfolder/file.txt
# split = [d:, Myfolder , file.txt]
name = fileName.split('/')[-1] # file.txt
name = name.ljust(HEADER_FILENAME_LENGTH,'*') # file.txt**********************
qty = str(qty)
qty = qty.ljust(HEADER_FILESIZE_LENGTH, '*') # 409*****************
return (name + qty) # file.txt**********************409*****************
def embed(resultant_image,source_image,file_to_embed):
# Load the image
image = cv2.imread(source_image , cv2.IMREAD_COLOR)
if image is None:
print(source_image,"not found!")
return
file_size = getFileSize(file_to_embed)
if(file_size == 0) :
print(file_to_embed,"not found!")
return
height, width , _ = image.shape
if(height*width < file_size + HEADER_LENGTH):
print("Insufficient Embedding Space")
return
header = generateHeader(file_to_embed)
fileHandler = open(file_to_embed,'rb') # open file in read + binary mode
i = 0
cnt = 0
data = 0
keepEmbedding = True
while i<height and keepEmbedding:
j = 0
while j < width:
# get data
if cnt < HEADER_LENGTH: # either from header
data = ord(header[cnt])
else : # or from file
data = fileHandler.read(1) # read one byte from the file
if (data) :
# as the file is opened in binary mode
# so we get byte objects on read. ex : b'> Reading Books (1 hr)\r\n'
# the byte object dont support bitwise operations
# hence they are to be converted to int
data = int.from_bytes(data, byteorder='big')
else : #EOF
keepEmbedding = False
break
bits = getBits(data)
image[i,j,2] = (image[i,j,2] & ~0x7) | bits[0] # embed in red band
image[i,j,1] = (image[i,j,1] & ~0x7) | bits[1] # embed in green band
image[i,j,0] = (image[i,j,0] & ~0x3) | bits[2] # embed in blue band
cnt+=1
j+=1
i+=1
#close the file
fileHandler.close()
#save back the image
cv2.imwrite(resultant_image,image)
print('Embedding Done!')
def extract(target_image, save_in_folder):
# load the image
image = cv2.imread(target_image,cv2.IMREAD_COLOR)
if image is None:
print(image,"not found!")
return
height, width , _ = image.shape
header = ''
fileHandler = None
i = 0
cnt = 0
keepExtracting = True
while i<height and keepExtracting:
j = 0
while j<width:
# extract the data
bit1 = image[i,j,2] & 0x7 # extract from red band
bit2 = image[i,j,1] & 0x7 # extract from green band
bit3 = image[i,j,0] & 0x3 # extract from blue band
data = getByte([bit1 , bit2 , bit3])
# put the data
if cnt < HEADER_LENGTH: # either into the header
header = header + chr(data)
else : # or in file
if cnt == HEADER_LENGTH:
fileName = save_in_folder + '/' + header[:HEADER_FILENAME_LENGTH].strip('*')
fileSize = int(header[HEADER_FILENAME_LENGTH:].strip('*')) + cnt
fileHandler = open(fileName,'wb')
if cnt< fileSize:
data = int.to_bytes(int(data), 1 , byteorder='big')
fileHandler.write(data)
else:
fileHandler.close()
keepExtracting = False
break
cnt += 1
j += 1
i+=1
print('Extraction Done!')
def main():
print("Enter your choice : ")
print("1. Embed the document in the image ")
print("2. Extract the document from the image")
choice = int(input("Choice : "));
if choice == 1 :
resultant_image = input("Enter the path for the resultant image : ") # ex : g:/result.png
source_image = input("Enter the path for the source image : ") # ex : g:/Sagar/Photos/DSC_.jpg
file_to_embed = input("Enter the path for the file to be embedd : ") # ex : G:/Sagar/Sagar/2020.txt
embed(resultant_image, source_image , file_to_embed)
elif choice == 2:
target_image = input("Enter the target image : ") # i.e the image containing the embedded info. ex: g:/result.png
save_in_folder = input("Enter the path where the extracted file to be saved : ") # ex : f:
extract(target_image,save_in_folder)
else:
print("Invalid choice")
if __name__ == '__main__':
main()