-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathencode.py
56 lines (45 loc) · 1.54 KB
/
encode.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
import sys
import math
from os import path
import cv2
import numpy as np
# Embed secret in the n least significant bit.
# Lower n make picture less loss but lesser storage capacity.
BITS = 2
HIGH_BITS = 256 - (1 << BITS)
LOW_BITS = (1 << BITS) - 1
BYTES_PER_BYTE = math.ceil(8 / BITS)
FLAG = '%'
def insert(img_path, msg):
img = cv2.imread(img_path, cv2.IMREAD_ANYCOLOR)
# Save origin shape to restore image
ori_shape = img.shape
print(ori_shape)
max_bytes = ori_shape[0] * ori_shape[1] // BYTES_PER_BYTE
# Encode message with length
msg = '{}{}{}'.format(len(msg), FLAG, msg)
assert max_bytes >= len(
msg), "Message greater than capacity:{}".format(max_bytes)
data = np.reshape(img, -1)
for (idx, val) in enumerate(msg):
encode(data[idx*BYTES_PER_BYTE: (idx+1) * BYTES_PER_BYTE], val)
img = np.reshape(data, ori_shape)
filename, _ = path.splitext(img_path)
filename += '_lsb_embeded' + ".png"
cv2.imwrite(filename, img)
return filename
def encode(block, data):
# returns the Unicode code from a given character
data = ord(data)
for idx in range(len(block)):
block[idx] &= HIGH_BITS
block[idx] |= (data >> (BITS * idx)) & LOW_BITS
if __name__ == '__main__':
if len(sys.argv) == 3:
img_path = sys.argv[1]
msg = sys.argv[2]
else:
img_path = "./assets/ubuntu.jpg"
msg = 'We got our man. Leave from the shipping port, gate B by Friday evening.'
res_path = insert(img_path, msg)
print("Successfully embedded.")