ShieldX commited on
Commit
d737cb7
1 Parent(s): 866f827

Add application file

Browse files
Files changed (3) hide show
  1. Dockerfile +13 -0
  2. api.py +143 -0
  3. requirements.txt +5 -0
Dockerfile ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:latest
2
+
3
+ WORKDIR /code
4
+
5
+ COPY ./requirements.txt /code/requirements.txt
6
+
7
+ RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
8
+
9
+ COPY . .
10
+
11
+ EXPOSE 7860
12
+
13
+ CMD ["uvicorn", "app.api:app", "--host", "0.0.0.0", "--port", "7860"]
api.py ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Importing the required libraries
2
+ import cv2
3
+ from fastapi import FastAPI, File, UploadFile, HTTPException, Response, Form
4
+ from fastapi.middleware.cors import CORSMiddleware
5
+ import numpy as np
6
+ import json
7
+ import base64
8
+
9
+ app = FastAPI()
10
+
11
+ # Allowing CORS (Cross-Origin Resource Sharing)
12
+ app.add_middleware(
13
+ CORSMiddleware,
14
+ allow_origins=["*"],
15
+ allow_credentials=True,
16
+ allow_methods=["*"],
17
+ allow_headers=["*"],
18
+ )
19
+
20
+ # @app.on_event("startup")
21
+ # def save_openapi_json():
22
+ # openapi_data = app.openapi()
23
+ # with open("openapi.json", "w") as file:
24
+ # json.dump(openapi_data, file)
25
+
26
+ # Converting types to binary
27
+ def msg_to_bin(msg):
28
+ if type(msg) == str:
29
+ return ''.join([format(ord(i), "08b") for i in msg])
30
+ elif type(msg) == bytes or type(msg) == np.ndarray:
31
+ return [format(i, "08b") for i in msg]
32
+ elif type(msg) == int or type(msg) == np.uint8:
33
+ return format(msg, "08b")
34
+ else:
35
+ raise TypeError("Input type not supported")
36
+
37
+ # defining function to hide the secret message into the image
38
+ def hide_data(img, secret_msg):
39
+ # calculating the maximum bytes for encoding
40
+ nBytes = img.shape[0] * img.shape[1] * 3 // 8
41
+ print("Maximum Bytes for encoding:", nBytes)
42
+ # checking whether the number of bytes for encoding is less
43
+ # than the maximum bytes in the image
44
+ if len(secret_msg) > nBytes:
45
+ raise ValueError("Error encountered insufficient bytes, need bigger image or less data!!")
46
+ secret_msg += '#####' # we can utilize any string as the delimiter
47
+ dataIndex = 0
48
+ # converting the input data to binary format using the msg_to_bin() function
49
+ bin_secret_msg = msg_to_bin(secret_msg)
50
+
51
+ # finding the length of data that requires to be hidden
52
+ dataLen = len(bin_secret_msg)
53
+ for values in img:
54
+ for pixels in values:
55
+ # converting RGB values to binary format
56
+ r, g, b = msg_to_bin(pixels)
57
+ # modifying the LSB only if there is data remaining to store
58
+ if dataIndex < dataLen:
59
+ # hiding the data into LSB of Red pixel
60
+ pixels[0] = int(r[:-1] + bin_secret_msg[dataIndex], 2)
61
+ dataIndex += 1
62
+ if dataIndex < dataLen:
63
+ # hiding the data into LSB of Green pixel
64
+ pixels[1] = int(g[:-1] + bin_secret_msg[dataIndex], 2)
65
+ dataIndex += 1
66
+ if dataIndex < dataLen:
67
+ # hiding the data into LSB of Blue pixel
68
+ pixels[2] = int(b[:-1] + bin_secret_msg[dataIndex], 2)
69
+ dataIndex += 1
70
+ # if data is encoded, break out the loop
71
+ if dataIndex >= dataLen:
72
+ break
73
+
74
+ return img
75
+
76
+ def show_data(img):
77
+ bin_data = ""
78
+ for values in img:
79
+ for pixels in values:
80
+ # converting the Red, Green, Blue values into binary format
81
+ r, g, b = msg_to_bin(pixels)
82
+ # data extraction from the LSB of Red pixel
83
+ bin_data += r[-1]
84
+ # data extraction from the LSB of Green pixel
85
+ bin_data += g[-1]
86
+ # data extraction from the LSB of Blue pixel
87
+ bin_data += b[-1]
88
+ # split by 8-Bits
89
+ allBytes = [bin_data[i: i + 8] for i in range(0, len(bin_data), 8)]
90
+ # converting from bits to characters
91
+ decodedData = ""
92
+ for bytes in allBytes:
93
+ decodedData += chr(int(bytes, 2))
94
+ # checking if we have reached the delimiter which is "#####"
95
+ if decodedData[-5:] == "#####":
96
+ break
97
+ # print(decodedData)
98
+ # removing the delimiter to display the actual hidden message
99
+ return decodedData[:-5]
100
+
101
+ @app.get("/")
102
+ async def root():
103
+ return {"message": "Server is alive"}
104
+
105
+ @app.post("/hide_message")
106
+ async def hide_message(image: UploadFile = File(...), secret_msg: str = Form(...)):
107
+ try:
108
+ # Read image using OpenCV
109
+ content = await image.read()
110
+ nparr = np.frombuffer(content, np.uint8)
111
+ img = cv2.imdecode(nparr, cv2.IMREAD_UNCHANGED)
112
+
113
+ # Hide the secret message in the image
114
+ encoded_image = hide_data(img, secret_msg)
115
+
116
+ # Convert the image to bytes
117
+ _, encoded_image_data = cv2.imencode(".png", encoded_image)
118
+ encoded_image_bytes = encoded_image_data.tobytes()
119
+
120
+ # Encode the image bytes to base64
121
+ encoded_image_base64 = base64.b64encode(encoded_image_bytes).decode()
122
+
123
+ # Return the base64 encoded image
124
+ return {"base64_image": encoded_image_base64}
125
+ except Exception as e:
126
+ raise HTTPException(status_code=500, detail=str(e))
127
+
128
+
129
+ # API endpoint to retrieve the secret message from an image
130
+ @app.post("/retrieve_message")
131
+ async def retrieve_message(image: UploadFile = File(...)):
132
+ try:
133
+ # Read image using OpenCV
134
+ content = await image.read()
135
+ nparr = np.frombuffer(content, np.uint8)
136
+ img = cv2.imdecode(nparr, cv2.IMREAD_UNCHANGED)
137
+
138
+ # Retrieve the hidden message from the image
139
+ decoded_message = show_data(img)
140
+
141
+ return {"decoded_message": decoded_message}
142
+ except Exception as e:
143
+ raise HTTPException(status_code=500, detail=str(e))
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ opencv-python-headless
2
+ fastapi
3
+ python-multipart
4
+ numpy
5
+ uvicorn