Spaces:
Sleeping
Sleeping
finished poc?
Browse files- .gitignore +3 -1
- README.md +1 -1
- app.py +29 -15
- base_images/pixabay-animal-gcc745627b_1280.jpg +0 -0
- base_images/pixabay-monkey-g0781002cb_1280.jpg +0 -0
- base_images/pixabay-monkey-ga15a9e970_1280.jpg +0 -0
- monkey.py +45 -34
- requirements.py +61 -0
.gitignore
CHANGED
@@ -157,4 +157,6 @@ cython_debug/
|
|
157 |
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
158 |
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
159 |
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
160 |
-
#.idea/
|
|
|
|
|
|
157 |
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
158 |
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
159 |
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
160 |
+
#.idea/
|
161 |
+
|
162 |
+
flagged/
|
README.md
CHANGED
@@ -10,4 +10,4 @@ pinned: false
|
|
10 |
license: gpl-3.0
|
11 |
---
|
12 |
|
13 |
-
|
|
|
10 |
license: gpl-3.0
|
11 |
---
|
12 |
|
13 |
+
Yes, this allows you to encode data into monkeys.
|
app.py
CHANGED
@@ -2,18 +2,32 @@ import gradio as gr
|
|
2 |
import monkey
|
3 |
import tempfile
|
4 |
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
import monkey
|
3 |
import tempfile
|
4 |
|
5 |
+
|
6 |
+
def encoder(data):
|
7 |
+
fp = tempfile.NamedTemporaryFile(suffix=".png").name
|
8 |
+
img = monkey.encode(data)
|
9 |
+
img.save(fp)
|
10 |
+
return img, fp
|
11 |
+
|
12 |
+
|
13 |
+
def decoder(input_image):
|
14 |
+
return monkey.decode(input_image)
|
15 |
+
|
16 |
+
|
17 |
+
idecoder = gr.Interface(
|
18 |
+
fn=decoder,
|
19 |
+
inputs=gr.Image(type="pil", label="image to decode"),
|
20 |
+
outputs=gr.Text(label="decoded text"),
|
21 |
+
description="### Decode the data stored in your monkeys into readable text.",
|
22 |
+
)
|
23 |
+
|
24 |
+
iencoder = gr.Interface(
|
25 |
+
fn=encoder,
|
26 |
+
inputs=gr.Text(label="text to decode"),
|
27 |
+
outputs=[gr.Image(label="image"), gr.File(label="download file")],
|
28 |
+
description="### Encode your highly sensitive text data (/s) into trustworthy monkeys.",
|
29 |
+
)
|
30 |
+
|
31 |
+
iface = gr.TabbedInterface([iencoder, idecoder], ["encoder", "decoder"])
|
32 |
+
|
33 |
+
iface.launch()
|
base_images/pixabay-animal-gcc745627b_1280.jpg
ADDED
![]() |
base_images/pixabay-monkey-g0781002cb_1280.jpg
ADDED
![]() |
base_images/pixabay-monkey-ga15a9e970_1280.jpg
ADDED
![]() |
monkey.py
CHANGED
@@ -1,91 +1,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
1 |
from email.mime import base
|
2 |
import glob
|
3 |
import random
|
4 |
from PIL import Image
|
5 |
|
|
|
6 |
def random_base_img():
|
7 |
img_fn = random.choice(glob.glob("./base_images/*.jpg"))
|
8 |
return Image.open(img_fn, "r")
|
9 |
|
10 |
|
11 |
def modify_pixel(pixel, data):
|
12 |
-
data_lst = [format(ord(d),
|
13 |
data_len = len(data_lst)
|
14 |
imdata = iter(pixel)
|
15 |
-
|
16 |
for i in range(data_len):
|
17 |
-
pix = [
|
18 |
-
|
19 |
-
|
20 |
-
|
|
|
|
|
|
|
21 |
# Pixel value should be made
|
22 |
# odd for 1 and even for 0
|
23 |
for j in range(0, 8):
|
24 |
-
if
|
25 |
pix[j] -= 1
|
26 |
-
|
27 |
-
elif
|
28 |
-
if
|
29 |
pix[j] -= 1
|
30 |
else:
|
31 |
pix[j] += 1
|
32 |
-
|
33 |
# Eighth pixel of every set tells
|
34 |
# whether to stop ot read further.
|
35 |
# 0 means keep reading; 1 means thec
|
36 |
# message is over.
|
37 |
-
if
|
38 |
-
if
|
39 |
-
if
|
40 |
pix[-1] -= 1
|
41 |
else:
|
42 |
pix[-1] += 1
|
43 |
-
|
44 |
else:
|
45 |
-
if
|
46 |
pix[-1] -= 1
|
47 |
-
|
48 |
pix = tuple(pix)
|
49 |
yield pix[0:3]
|
50 |
yield pix[3:6]
|
51 |
yield pix[6:9]
|
52 |
|
53 |
-
|
54 |
-
|
55 |
base_img = random_base_img()
|
56 |
w = base_img.size[0]
|
57 |
(x, y) = (0, 0)
|
58 |
-
|
59 |
for pixel in modify_pixel(base_img.getdata(), data):
|
60 |
base_img.putpixel((x, y), pixel)
|
61 |
-
if
|
62 |
x = 0
|
63 |
y += 1
|
64 |
else:
|
65 |
x += 1
|
66 |
|
67 |
-
print("decoded:", decode(base_img.copy()))
|
68 |
return base_img.copy()
|
69 |
-
|
70 |
|
71 |
def decode(img):
|
72 |
-
data =
|
73 |
imgdata = iter(img.getdata())
|
74 |
|
75 |
-
while
|
76 |
-
pixels = [
|
77 |
-
|
78 |
-
|
|
|
|
|
|
|
79 |
|
80 |
# string of binary data
|
81 |
-
binstr =
|
82 |
|
83 |
for i in pixels[:8]:
|
84 |
-
if
|
85 |
-
binstr +=
|
86 |
else:
|
87 |
-
binstr +=
|
88 |
|
89 |
data += chr(int(binstr, 2))
|
90 |
-
if
|
91 |
-
return data
|
|
|
1 |
+
"""
|
2 |
+
Note, this heavily builds upon
|
3 |
+
https://gist.github.com/goelashwin36/6847a974c9b7b2ca500154d5c89d1d76
|
4 |
+
"""
|
5 |
+
|
6 |
from email.mime import base
|
7 |
import glob
|
8 |
import random
|
9 |
from PIL import Image
|
10 |
|
11 |
+
|
12 |
def random_base_img():
|
13 |
img_fn = random.choice(glob.glob("./base_images/*.jpg"))
|
14 |
return Image.open(img_fn, "r")
|
15 |
|
16 |
|
17 |
def modify_pixel(pixel, data):
|
18 |
+
data_lst = [format(ord(d), "08b") for d in data]
|
19 |
data_len = len(data_lst)
|
20 |
imdata = iter(pixel)
|
21 |
+
|
22 |
for i in range(data_len):
|
23 |
+
pix = [
|
24 |
+
value
|
25 |
+
for value in imdata.__next__()[:3]
|
26 |
+
+ imdata.__next__()[:3]
|
27 |
+
+ imdata.__next__()[:3]
|
28 |
+
]
|
29 |
+
|
30 |
# Pixel value should be made
|
31 |
# odd for 1 and even for 0
|
32 |
for j in range(0, 8):
|
33 |
+
if data_lst[i][j] == "0" and pix[j] % 2 != 0:
|
34 |
pix[j] -= 1
|
35 |
+
|
36 |
+
elif data_lst[i][j] == "1" and pix[j] % 2 == 0:
|
37 |
+
if pix[j] != 0:
|
38 |
pix[j] -= 1
|
39 |
else:
|
40 |
pix[j] += 1
|
41 |
+
|
42 |
# Eighth pixel of every set tells
|
43 |
# whether to stop ot read further.
|
44 |
# 0 means keep reading; 1 means thec
|
45 |
# message is over.
|
46 |
+
if i == data_len - 1:
|
47 |
+
if pix[-1] % 2 == 0:
|
48 |
+
if pix[-1] != 0:
|
49 |
pix[-1] -= 1
|
50 |
else:
|
51 |
pix[-1] += 1
|
52 |
+
|
53 |
else:
|
54 |
+
if pix[-1] % 2 != 0:
|
55 |
pix[-1] -= 1
|
56 |
+
|
57 |
pix = tuple(pix)
|
58 |
yield pix[0:3]
|
59 |
yield pix[3:6]
|
60 |
yield pix[6:9]
|
61 |
|
62 |
+
|
63 |
+
def encode(data):
|
64 |
base_img = random_base_img()
|
65 |
w = base_img.size[0]
|
66 |
(x, y) = (0, 0)
|
67 |
+
|
68 |
for pixel in modify_pixel(base_img.getdata(), data):
|
69 |
base_img.putpixel((x, y), pixel)
|
70 |
+
if x == w - 1:
|
71 |
x = 0
|
72 |
y += 1
|
73 |
else:
|
74 |
x += 1
|
75 |
|
|
|
76 |
return base_img.copy()
|
77 |
+
|
78 |
|
79 |
def decode(img):
|
80 |
+
data = ""
|
81 |
imgdata = iter(img.getdata())
|
82 |
|
83 |
+
while True:
|
84 |
+
pixels = [
|
85 |
+
value
|
86 |
+
for value in imgdata.__next__()[:3]
|
87 |
+
+ imgdata.__next__()[:3]
|
88 |
+
+ imgdata.__next__()[:3]
|
89 |
+
]
|
90 |
|
91 |
# string of binary data
|
92 |
+
binstr = ""
|
93 |
|
94 |
for i in pixels[:8]:
|
95 |
+
if i % 2 == 0:
|
96 |
+
binstr += "0"
|
97 |
else:
|
98 |
+
binstr += "1"
|
99 |
|
100 |
data += chr(int(binstr, 2))
|
101 |
+
if pixels[-1] % 2 != 0:
|
102 |
+
return data
|
requirements.py
ADDED
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
aiohttp==3.8.1
|
2 |
+
aiosignal==1.2.0
|
3 |
+
analytics-python==1.4.0
|
4 |
+
anyio==3.6.1
|
5 |
+
asgiref==3.5.2
|
6 |
+
async-timeout==4.0.2
|
7 |
+
attrs==21.4.0
|
8 |
+
backoff==1.10.0
|
9 |
+
bcrypt==3.2.2
|
10 |
+
black==22.3.0
|
11 |
+
certifi==2022.5.18.1
|
12 |
+
cffi==1.15.0
|
13 |
+
charset-normalizer==2.0.12
|
14 |
+
click==8.1.3
|
15 |
+
cryptography==37.0.2
|
16 |
+
cycler==0.11.0
|
17 |
+
fastapi==0.78.0
|
18 |
+
ffmpy==0.3.0
|
19 |
+
fonttools==4.33.3
|
20 |
+
frozenlist==1.3.0
|
21 |
+
gradio==3.0.13
|
22 |
+
h11==0.13.0
|
23 |
+
idna==3.3
|
24 |
+
Jinja2==3.1.2
|
25 |
+
kiwisolver==1.4.2
|
26 |
+
linkify-it-py==1.0.3
|
27 |
+
markdown-it-py==2.1.0
|
28 |
+
MarkupSafe==2.1.1
|
29 |
+
matplotlib==3.5.2
|
30 |
+
mdit-py-plugins==0.3.0
|
31 |
+
mdurl==0.1.1
|
32 |
+
monotonic==1.6
|
33 |
+
multidict==6.0.2
|
34 |
+
mypy-extensions==0.4.3
|
35 |
+
numpy==1.22.4
|
36 |
+
orjson==3.7.2
|
37 |
+
packaging==21.3
|
38 |
+
pandas==1.4.2
|
39 |
+
paramiko==2.11.0
|
40 |
+
pathspec==0.9.0
|
41 |
+
Pillow==9.1.1
|
42 |
+
platformdirs==2.5.2
|
43 |
+
pycparser==2.21
|
44 |
+
pycryptodome==3.14.1
|
45 |
+
pydantic==1.9.1
|
46 |
+
pydub==0.25.1
|
47 |
+
PyNaCl==1.5.0
|
48 |
+
pyparsing==3.0.9
|
49 |
+
python-dateutil==2.8.2
|
50 |
+
python-multipart==0.0.5
|
51 |
+
pytz==2022.1
|
52 |
+
requests==2.27.1
|
53 |
+
six==1.16.0
|
54 |
+
sniffio==1.2.0
|
55 |
+
starlette==0.19.1
|
56 |
+
tomli==2.0.1
|
57 |
+
typing_extensions==4.2.0
|
58 |
+
uc-micro-py==1.0.1
|
59 |
+
urllib3==1.26.9
|
60 |
+
uvicorn==0.17.6
|
61 |
+
yarl==1.7.2
|