Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Thick Wrappers #9

Open
wants to merge 227 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
227 commits
Select commit Hold shift + click to select a range
4d5dc75
Initial commit
DavidLlanio Aug 28, 2023
6bc8fd6
Updated Python Version lint.yaml
DavidLlanio Aug 31, 2023
e89adcb
Update README.md
DavidLlanio Sep 1, 2023
06f09fd
Merge pull request #1 from DavidLlanio/sample
DavidLlanio Sep 1, 2023
4b7cd52
init
maxence-glt Sep 1, 2023
abfd798
static file added
maxence-glt Sep 1, 2023
8956904
samples deleted
maxence-glt Sep 1, 2023
d39f289
Merge pull request #2 from DavidLlanio/decrypt_text
maxence-glt Sep 1, 2023
6cf1aa2
pre-commit lint
DavidLlanio Sep 1, 2023
05cc2b7
Merge pull request #3 from DavidLlanio/decrypt_text
DavidLlanio Sep 1, 2023
062f8c5
Fixed Linting Sheesh
DavidLlanio Sep 1, 2023
1133a76
Merge pull request #4 from DavidLlanio/decrypt_text
DavidLlanio Sep 1, 2023
68285cc
Created general layout of GUI, Added pydis_logo
DavidLlanio Sep 1, 2023
46f8138
Added nicegui to requirements
DavidLlanio Sep 1, 2023
da38897
Images can be uploaded and stored in static folder
DavidLlanio Sep 1, 2023
97e8820
Encryption function
Sep 2, 2023
77e5a27
Placeholders for encryption and decryption events
DavidLlanio Sep 2, 2023
4e94039
Created function that take binary in and spits out the ascii version
maxence-glt Sep 2, 2023
7c874bd
Merge pull request #5 from DavidLlanio/binary_to_ascii
maxence-glt Sep 2, 2023
7f8341d
Revise pixel selection
Sep 2, 2023
bc4b752
Add message padding
Sep 2, 2023
78472dd
pixel to hex func finished
maxence-glt Sep 2, 2023
b657b38
Added Pillow to requirements
DavidLlanio Sep 2, 2023
8336ee2
Created encrypt callback for encrypt button
DavidLlanio Sep 2, 2023
3db5ca0
Function to convert pixel to binary
maxence-glt Sep 2, 2023
4863afd
Text decyption layed out
maxence-glt Sep 2, 2023
219e047
Fix byte conversion bug
Sep 2, 2023
9ebaa16
FInxed linter
maxence-glt Sep 2, 2023
82b78f8
Merge pull request #7 from DavidLlanio/linting-testing
maxence-glt Sep 2, 2023
74155f2
Changed copyright statement
DavidLlanio Sep 2, 2023
7d025df
Update LICENSE (mispelt my username)
maxence-glt Sep 2, 2023
50262fc
decrypt callback function and file path mods
DavidLlanio Sep 2, 2023
8e3d6df
Created dataclass to keep track of file paths
DavidLlanio Sep 2, 2023
b86a0c5
image to image initial implementation
Jaavv Sep 3, 2023
e214c88
Callback functions use filepaths class object
DavidLlanio Sep 3, 2023
9c88c85
Updated decryption callback function docs
DavidLlanio Sep 3, 2023
e387e34
Small correction on if statement
DavidLlanio Sep 3, 2023
274fec9
Merge branch 'stega' into dev
Jaavv Sep 3, 2023
69319b9
Merge pull request #8 from DavidLlanio/stega
Jaavv Sep 3, 2023
c144da3
Static folder discoverable by GUI
DavidLlanio Sep 3, 2023
5bc9093
Modified all_pixels_to_binary funciton to allow for Pillow objects to…
maxence-glt Sep 3, 2023
cea5dbd
Merge branch 'main' into decryption
maxence-glt Sep 3, 2023
58f35dd
Merge pull request #9 from DavidLlanio/decryption
maxence-glt Sep 3, 2023
421c409
GUI now pops up output with option to download
DavidLlanio Sep 3, 2023
f60ba8f
Merge remote-tracking branch 'main/dev' into gui
DavidLlanio Sep 3, 2023
367119a
Merge pull request #10 from DavidLlanio/gui
DavidLlanio Sep 3, 2023
4a58371
Merge remote-tracking branch 'origin/dev' into dev
Jaavv Sep 3, 2023
01e400c
added Pixel class
Jaavv Sep 3, 2023
fc65405
added get_rgb methods
Jaavv Sep 3, 2023
d8963a9
added typing to methods and override toString
Jaavv Sep 3, 2023
4a5cebf
Add file to test encryption/decryption, and sample image
Sep 3, 2023
e7ae25a
Decryption function FINISHED. Need to add lexicon
maxence-glt Sep 3, 2023
3a66296
Flake8 check passed
maxence-glt Sep 3, 2023
d7226bf
Merge pull request #11 from DavidLlanio/decypt_text
maxence-glt Sep 3, 2023
17cdd0a
StegaImage refactor
Jaavv Sep 3, 2023
de7be21
Removed print examples
maxence-glt Sep 4, 2023
bbd21d4
stega tweaks
Jaavv Sep 4, 2023
ba54cc6
Copy image and strip input text
Sep 4, 2023
d8d91e8
Removed string fabricators
maxence-glt Sep 4, 2023
25a6a33
Removed redundant string fabricators
maxence-glt Sep 4, 2023
e86c1da
Merge branch 'dev' of https://github.com/DavidLlanio/cj10_the_thick_w…
Jaavv Sep 4, 2023
837d9fe
Merge pull request #6 from DavidLlanio/encrypt-text
DavidLlanio Sep 4, 2023
ba3194a
Merge branch 'main' of https://github.com/DavidLlanio/cj10_the_thick_…
DavidLlanio Sep 4, 2023
74e8108
Remove testing image
Sep 4, 2023
3d8f133
Add function to decrypt secret image
Robin5605 Sep 4, 2023
1579828
Lint
Robin5605 Sep 4, 2023
9e6960d
Merge pull request #12 from DavidLlanio/decrypt-image
DavidLlanio Sep 4, 2023
7fa0d4d
Sample pictures
DavidLlanio Sep 4, 2023
149676a
Changed print pos
maxence-glt Sep 4, 2023
c46547f
Added encrypt text function
DavidLlanio Sep 4, 2023
99ffd28
Fix row-column order
Sep 4, 2023
6ca7af2
Merge branch 'main' of https://github.com/DavidLlanio/cj10_the_thick_…
DavidLlanio Sep 4, 2023
55ef6f6
Actually fix column-row bug
Sep 4, 2023
7ecbcfc
Merge branch 'main' of https://github.com/DavidLlanio/cj10_the_thick_…
DavidLlanio Sep 4, 2023
2203629
Remove breakpoint
Sep 4, 2023
388cc7a
Forcing all image files to be in png format
DavidLlanio Sep 4, 2023
0ae1926
Merge pull request #13 from DavidLlanio/gui
DavidLlanio Sep 4, 2023
33cbac9
added Pixel class to accept tuple args
Jaavv Sep 4, 2023
59d58b7
RGB -> BGR
maxence-glt Sep 4, 2023
7acd803
Merge branch 'dev' of https://github.com/DavidLlanio/cj10_the_thick_w…
maxence-glt Sep 4, 2023
a76a89f
Merge branch 'main' of https://github.com/DavidLlanio/cj10_the_thick_…
maxence-glt Sep 4, 2023
027e71a
Stega image fixes
Jaavv Sep 4, 2023
588f34a
Merge remote-tracking branch 'origin/dev' into dev
Jaavv Sep 4, 2023
7af78dc
Stega image tweaks
Jaavv Sep 4, 2023
e7a858c
added Steganograpizer class
Jaavv Sep 4, 2023
ed0abf9
added numpy for dependency
Jaavv Sep 4, 2023
cc5d000
added Steganographizer class
Jaavv Sep 5, 2023
1517145
minor tweaks
Jaavv Sep 5, 2023
60754a1
added encrypted image
Jaavv Sep 5, 2023
c752b0f
Binary decoder almost complete
maxence-glt Sep 5, 2023
f081dfd
Delimiter
maxence-glt Sep 5, 2023
4baac58
implemented Steganographizer to GUI
Jaavv Sep 5, 2023
6c57c4f
Gitignore updated
maxence-glt Sep 5, 2023
3e7711c
Merge branch 'dev' of https://github.com/DavidLlanio/cj10_the_thick_w…
maxence-glt Sep 5, 2023
9fdef1e
Added text decryption to GUI, removed textdownload
DavidLlanio Sep 5, 2023
b15caf2
Merge branch 'dev' of https://github.com/DavidLlanio/cj10_the_thick_w…
DavidLlanio Sep 5, 2023
a757adb
Modified binary_decoder to output text and flag
DavidLlanio Sep 5, 2023
df5ce00
Changed output text
DavidLlanio Sep 5, 2023
797a787
gitignore update
maxence-glt Sep 5, 2023
834a6f7
Refactored much of text decryption
maxence-glt Sep 5, 2023
4b92d12
Removed print statement
DavidLlanio Sep 5, 2023
9ed2d40
Merge branch 'dev' of https://github.com/DavidLlanio/cj10_the_thick_w…
DavidLlanio Sep 5, 2023
dbbf2a3
gitignore whole static folder fix
Jaavv Sep 5, 2023
e0454f0
StegaImage refactor
Jaavv Sep 5, 2023
04609f1
StegaImage refactor
Jaavv Sep 5, 2023
ce4410c
rename to proper method
Jaavv Sep 5, 2023
e94b04e
Steganographizer refactor
Jaavv Sep 5, 2023
5d4eacb
Don't assume 24-bit depth images
Robin5605 Sep 5, 2023
c152e17
Actually call decrypt_image from UI
Robin5605 Sep 5, 2023
5fed358
Steganographizer refactor to static method
Jaavv Sep 5, 2023
444f438
tweaks
Jaavv Sep 5, 2023
ab8e366
minor comment update
Jaavv Sep 5, 2023
da88f16
minor tweaks
Jaavv Sep 5, 2023
88f9d6e
docstring update
Jaavv Sep 5, 2023
ae511ed
encrypt_image static method change
Jaavv Sep 5, 2023
dc07f71
Initial text upload version
Sep 5, 2023
df9e6d0
Merge branch 'dev' of https://github.com/DavidLlanio/cj10_the_thick_w…
DavidLlanio Sep 6, 2023
90f6e89
Merge pull request #14 from DavidLlanio/decrypt-image
DavidLlanio Sep 6, 2023
31ab671
Merge branch 'dev' of https://github.com/DavidLlanio/cj10_the_thick_w…
DavidLlanio Sep 6, 2023
814c1f4
Update README.md
maxence-glt Sep 6, 2023
72ba881
Fixed bug output image wouldn't save
DavidLlanio Sep 6, 2023
9085426
Shortened convert_pixels_to_binary function
maxence-glt Sep 6, 2023
02269f7
Merge branch 'dev' of https://github.com/DavidLlanio/cj10_the_thick_w…
maxence-glt Sep 6, 2023
a38c9e0
decrypt and encrypt functions started
maxence-glt Sep 6, 2023
b8f3479
Added refactor files with function signatures
DavidLlanio Sep 6, 2023
183653d
Merge branch 'dev' of https://github.com/DavidLlanio/cj10_the_thick_w…
DavidLlanio Sep 6, 2023
4713251
Merge pull request #17 from DavidLlanio/text-upload
DavidLlanio Sep 6, 2023
1b734ab
Added text decrypter to decrypt.py
maxence-glt Sep 6, 2023
979c2bd
Added pixel iterator to utility
maxence-glt Sep 6, 2023
70f87fa
Changed funciton calls to match new files
maxence-glt Sep 6, 2023
7f3f86d
Removed redunant file
maxence-glt Sep 6, 2023
5306cf1
Hint typing and linter approved
maxence-glt Sep 6, 2023
ea1d126
Hint typing and changed import specifics
maxence-glt Sep 6, 2023
f267281
deleted pixel and image_to_image file
Jaavv Sep 6, 2023
1e2e354
Revise tests
Sep 6, 2023
3cb2ef8
added exif dataclass
Jaavv Sep 6, 2023
31033ef
Add exception handlers for invalid image and text files
Sep 6, 2023
cf7cf3e
Add decrypt handler
Sep 6, 2023
24fbe20
Revise exceptions
Sep 6, 2023
21620d1
apl_info fixes
Jaavv Sep 6, 2023
875fd2c
added functions:
Jaavv Sep 6, 2023
b9063b9
encrypt_image_to_image function update
Jaavv Sep 6, 2023
60a3231
ratio fixes
Jaavv Sep 6, 2023
ff7ae24
update_image method fix
Jaavv Sep 6, 2023
ebb8f1c
import cleanup
Jaavv Sep 6, 2023
66da1fe
Merge pull request #19 from DavidLlanio/image_handler
DavidLlanio Sep 7, 2023
6d0c222
GUI does not resize images anymore
DavidLlanio Sep 7, 2023
c43bb02
Fixed relative import
DavidLlanio Sep 7, 2023
51df3b3
Merge pull request #20 from DavidLlanio/gui
DavidLlanio Sep 7, 2023
1bdd407
Merge pull request #18 from DavidLlanio/numpy-encrypt
DavidLlanio Sep 7, 2023
18ff9d5
Merge pull request #21 from DavidLlanio/numpy-encrypt
Sep 7, 2023
77b0cf5
resize_image implementation
Jaavv Sep 7, 2023
30d2696
encrypt_image_to_image function fix
Jaavv Sep 7, 2023
fc34a31
resize_image logic tweaks and embed_exif docstring update
Jaavv Sep 7, 2023
1892f0c
resize_image magic number fix
Jaavv Sep 7, 2023
8734f9e
lsb and msb function docstring update
Jaavv Sep 7, 2023
9237514
Fix encryption bug, optimize string encoding
Sep 7, 2023
bb76a4b
added file to store constant values
Jaavv Sep 7, 2023
4db53c7
added for package fixes
Jaavv Sep 7, 2023
28986f2
Basic styling
DavidLlanio Sep 7, 2023
026417d
delete unused files
Jaavv Sep 7, 2023
b8e51f9
image encryption function fixes
Jaavv Sep 7, 2023
2c3e4db
shift_image_bits_asarray function added, exif function fix, resize_im…
Jaavv Sep 7, 2023
75f9861
updated bit shift function
Jaavv Sep 7, 2023
1ca136e
minor tweaks
Jaavv Sep 7, 2023
6382a5e
Move image decryption into decrypt.py
Robin5605 Sep 7, 2023
cd1b417
Invoke moved function from main
Robin5605 Sep 7, 2023
3282d26
exif_embed_apl function rename
Jaavv Sep 7, 2023
e4c6475
exif_embed_apl function rename;
Jaavv Sep 7, 2023
b76adca
Test commit, added numpy to decrypt.py
maxence-glt Sep 7, 2023
20bf4f0
Removed placeholder funciton
DavidLlanio Sep 7, 2023
5e07cec
Merge pull request #22 from DavidLlanio/decrypt-image
DavidLlanio Sep 8, 2023
a18bd3d
Software Title Fix
Jaavv Sep 8, 2023
11fe9ca
exif Make Fix
Jaavv Sep 8, 2023
fadb5a2
module fix
Jaavv Sep 8, 2023
371b379
changed Image to array arg type
Jaavv Sep 8, 2023
a72130f
shift_image_bits_array image param change to array type; exif_model_b…
Jaavv Sep 8, 2023
6792758
ipp typo fix
Jaavv Sep 8, 2023
0cb685a
ipp typo fix
Jaavv Sep 8, 2023
423b6d1
Merge branch 'enc_image' into dev_jaavv_copy
Jaavv Sep 8, 2023
044093d
Dark mode added
DavidLlanio Sep 8, 2023
571f5d2
module fix
Jaavv Sep 8, 2023
f9b68f0
encrypt_image_to_image fix
Jaavv Sep 8, 2023
15f113d
resizing hotfix
Jaavv Sep 8, 2023
3dd24aa
Update
maxence-glt Sep 8, 2023
ce28fe0
Merge pull request #24 from DavidLlanio/gui
DavidLlanio Sep 8, 2023
5296717
Update tests
Sep 8, 2023
2895292
Improve docstrings
Sep 8, 2023
98c0eef
Updated README
DavidLlanio Sep 9, 2023
623f63b
Merge branch 'dev' into refactor-text
DavidLlanio Sep 9, 2023
cf7f483
Merge pull request #25 from DavidLlanio/refactor-text
DavidLlanio Sep 9, 2023
37b3a8f
Merge pull request #26 from DavidLlanio/gui
DavidLlanio Sep 9, 2023
7b81d18
wip: parse image size from exif
Robin5605 Sep 9, 2023
59ad152
Linting
DavidLlanio Sep 9, 2023
c899265
Removed regex package and global
DavidLlanio Sep 9, 2023
16ec150
Replaced function import with refactored function
DavidLlanio Sep 9, 2023
b6ec63e
Gracefully handle missing EXIF data
Robin5605 Sep 9, 2023
979b6cd
Fixed issure with text file upload
DavidLlanio Sep 9, 2023
ced3348
Merge branch 'dev' into decrypt-image
Robin5605 Sep 9, 2023
3fe3ba9
Merge pull request #27 from DavidLlanio/decrypt-image
Robin5605 Sep 9, 2023
194db8f
Linting
DavidLlanio Sep 9, 2023
e2e4db6
More linting
DavidLlanio Sep 9, 2023
f0025e9
Handle RGBA images
Sep 9, 2023
053ea16
Removed images from static
DavidLlanio Sep 9, 2023
0f27657
Merge branch 'main' into dev
DavidLlanio Sep 9, 2023
431fc1b
Linted gitignore
DavidLlanio Sep 9, 2023
81beb44
Merge branch 'dev' of https://github.com/DavidLlanio/cj10_the_thick_w…
DavidLlanio Sep 9, 2023
948b13d
Import changes to pass linting
DavidLlanio Sep 9, 2023
434b45c
Merge pull request #29 from DavidLlanio/dev
DavidLlanio Sep 9, 2023
c1f7d02
Merge branch 'dev' into fix-rgb
Sep 9, 2023
e1e0929
Merge pull request #30 from DavidLlanio/fix-rgb
Sep 9, 2023
6de4852
Update README.md
maxence-glt Sep 9, 2023
11f6669
Update decrypt.py
maxence-glt Sep 9, 2023
abf023b
Set up image tests, fix docstrings
Sep 9, 2023
0c28650
Improve project docstrings
Sep 9, 2023
7f24c47
Test unprintable chars
Sep 9, 2023
cba3fc0
Add file deletion
Sep 10, 2023
6d8a378
Flush on illegal file uploads
Sep 10, 2023
230b440
Merge pull request #31 from DavidLlanio/image-test
Sep 10, 2023
d19537a
Merge pull request #32 from DavidLlanio/file-delete
Sep 10, 2023
0b158ca
Fix test error
Sep 10, 2023
282842e
Merge pull request #33 from DavidLlanio/fix-tests
Sep 10, 2023
f694a8e
Merge pull request #34 from DavidLlanio/dev
Sep 10, 2023
4ba8021
Added GUI GIF to README
DavidLlanio Sep 13, 2023
73874ea
Fixed Link in README GIF
DavidLlanio Sep 13, 2023
a1a1bca
Fix formatting on GIF
DavidLlanio Sep 13, 2023
6211ec6
Add 'thick-wrappers/' from commit 'a1a1bca09fcb5b9fbce4d6c225001a271c…
janine9vn Sep 28, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions thick-wrappers/.github/workflows/lint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# GitHub Action Workflow enforcing our code style.

name: Lint

# Trigger the workflow on both push (to the main repository, on the main branch)
# and pull requests (against the main repository, but from any repo, from any branch).
on:
push:
branches:
- main
pull_request:
# Brand new concurrency setting! This ensures that not more than one run can be triggered for the same commit.
# It is useful for pull requests coming from the main repository since both triggers will match.
concurrency: lint-${{ github.sha }}

jobs:
lint:
runs-on: ubuntu-latest

env:
# The Python version your project uses. Feel free to change this if required.
PYTHON_VERSION: "3.11"

steps:
# Checks out the repository in the current folder.
- name: Checks out repository
uses: actions/checkout@v3

# Set up the right version of Python
- name: Set up Python ${{ env.PYTHON_VERSION }}
uses: actions/setup-python@v3
with:
python-version: ${{ env.PYTHON_VERSION }}

- name: Run pre-commit hooks
uses: pre-commit/[email protected]
37 changes: 37 additions & 0 deletions thick-wrappers/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Files generated by the interpreter
__pycache__/
*.py[cod]

# Environment specific
.venv
venv
.env
env

# Unittest reports
.coverage*

# Logs
*.log

# PyEnv version selector
.python-version

# Built objects
*.so
dist/
build/

# IDEs
# PyCharm
.idea/
# VSCode
.vscode/
# MacOS
.DS_Store

# Custom
.test_folder

# Image folder
static/
31 changes: 31 additions & 0 deletions thick-wrappers/.pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
## Pre-commit setup
# See https://github.com/python-discord/code-jam-template/tree/main#pre-commit-run-linting-before-committing

# Make sure to edit the `additional_dependencies` list if you want to add plugins

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.5.0
hooks:
- id: check-toml
- id: check-yaml
- id: end-of-file-fixer
- id: trailing-whitespace
args: [--markdown-linebreak-ext=md]

- repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.5.1
hooks:
- id: python-check-blanket-noqa

- repo: https://github.com/PyCQA/isort
rev: 5.12.0
hooks:
- id: isort

- repo: https://github.com/pycqa/flake8
rev: 4.0.1
hooks:
- id: flake8
additional_dependencies:
- flake8-docstrings~=1.6.0
7 changes: 7 additions & 0 deletions thick-wrappers/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Copyright 2023 The Thick Wrappers(DavidLlanio, maxence-glt, jaavv, standard-affect, Robin5605)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
71 changes: 71 additions & 0 deletions thick-wrappers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# In Plain Pixel
Created by "The Thick Wrappers" (github: DavidLlanio, maxence-glt, standard-affect, Jaavv, Robin5605) for the Python Discord 2023 CodeJam

## In Brief
In Plain Pixel is a Steganogrpahy application built completely with Python. Through this application, you are able to encrypt a valid input method (see below) into an image of your choice, or decrypt an image created through this application by simply inputting your decrypted image.

The following input types are supported for encryption:
- Typed Text
- Text File (*.txt)
- Image File (*.jpg, *.jpeg, *.png)

## What is Steganography?
Imagine you want to pass a note to your friend in a crowded library, but don't want to draw attention to the contents of the note or the note itself. Maybe you hide the message you want to pass in something inconspicuous like in the margins of a book or between the lines of sentences. In essence, you're hiding your message in plain sight.

[Steganography](https://en.wikipedia.org/wiki/Steganography) is similar to this concept, but with digital media, like pictures!

With steganography, you can hide something like a text message in a picture. You can even hide a picture in another picture!

### How does it work?

Computers only understand ones and zeros. Let's say a pixel in an RGB digital image has the integer values of [255, 255, 255], representing white.

255 in binary is 11111111
So the entire pixel is: [11111111, 11111111, 11111111]

With steganography, you can hide something in the [least significant bits](https://www.analog.com/en/design-center/glossary/lsb.html#:~:text=Least%2Dsignificant%20bit.,is%20the%20furthest%2Dright%20bit.) of this pixel. For example, let's hide the letter "H" in this pixel.

The [ASCII](https://www.asciitable.com/) code of the letter "H" is: 72 (decimal) or 1001000 (binary)

We can split up the binary of the ASCII for "H" into 3 parts:
- 1
- 001
- 000

Then clear and set the least significant bits of the pixel RGB values:
- R: 11111111 -> 11111000
- G: 11111111 -> 11111001
- B: 11111111 -> 11111111 (Last bit stays the same)

With these changes, the letter "H" is now hidden in the image with little impact to the image itself.

### How are we using Steganography?
The previous example features our method of hiding text in an image. We split the character's binary into 3 parts and hide the most significant bit in the lease significant bit of the blue channel, the 3 middle bits in the 3 least significant bits of the green channel, and the 3 least significant bits in the 3 least significant bits of the red channel.

We do this process for every character in the word, sentence, or paragraph.

For image inputs, we place the 4 most significant bits of the RGB channels of every pixel of the image you want to hide into the 4 least significant bits of the RGB channels of every pixel of the image you want to use as the cover.

When you decrypt an image inside of another image, you will get a lower quality version of the original image you wanted to hide because we cannot reproduce the least significant bits of the original image.

## How to Set up
- Download and unzip the repository, or clone it
- Use the change directory command into the repository at the level of main.py
```
cd cj10_the_thick_wrappers
```
- Install the dependencies:
```
python3 -m pip install -r dev-requirements.txt
```
## How to Start and Use GUI
After setup, run the main.py file to start the GUI:
```
python3 main.py
```

Sample use of GUI:

Encrypting text into an image

![In Plain Pixel](https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExenhtZHU1cGp2MmExZnk4NmZqcHV0ZHhmNHQ2ZWFsNWozdmFzbGJ4OCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/O7yq741e0EFZ4lLxpW/giphy.gif)
9 changes: 9 additions & 0 deletions thick-wrappers/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import pytest

from helper.utility import list_images


@pytest.fixture
def all_images():
"""Lists all images for testing"""
return list_images("static")
16 changes: 16 additions & 0 deletions thick-wrappers/dev-requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# This file contains all the development requirements for our linting toolchain.
# Don't forget to pin your dependencies!
# This list will have to be migrated if you wish to use another dependency manager.

# Base tools
flake8~=4.0.1
isort~=5.10.1
pre-commit~=2.17.0

# Flake8 plugins, see https://github.com/python-discord/code-jam-template/tree/main#plugin-list
flake8-docstrings~=1.6.0

# Core tools
nicegui~=1.3.13
Pillow~=10.0.0
numpy~=1.25.2
46 changes: 46 additions & 0 deletions thick-wrappers/helper/constant.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from enum import Enum

SOFTWARE_TITLE = "In Plain Pixel"
TEAM_MEMBERS = "Davr, Jaavv, maxence, standard_affect"
DESCRIPTION = "Python Discord Summer Code Jam 2023 - The Thick Wrappers Project"
EXIF_MAKE = "IPP"
STARTING_X = 0
STARTING_Y = 0
BITS_4 = 4
# R, G, B
N_PLANES = 3


class ResizeMode(Enum):
"""Enumeration for flag to shrink or leave image as is"""

DEFAULT = 0
SHRINK_TO_SCALE = 1


class Sizing(Enum):
"""Enumeration for flags on difference in secret image and cover image"""

SMALLER = 0
BIGGER = 1
TALLER = 2
WIDER = 3


class Direction(Enum):
"""Enumeration for direction of bit shift"""

LEFT = 0
RIGHT = 1
UP = 2
DOWN = 3


class ExifData(Enum):
"""Enumeration for metadata locations"""

MAKE = 271
MODEL = 272
ARTIST = 315
SOFTWARE = 305
DESCRIPTION = 270
57 changes: 57 additions & 0 deletions thick-wrappers/helper/decrypt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from PIL.Image import Image

from .constant import BITS_4, N_PLANES
from .utility import parse_exif, pixels_to_binary


def decrypt_text_from_image(img: Image) -> tuple[str, bool]:
"""
Decrypts an image encoded with text.

param img: A Pillow Image object containing message
This function iterates over an image's pixels and extracts the three least
significant bits of each color plane. These values are summed and converted
to the corresponding ASCII character. The function scans until it finds
the message delimiter ",,,.." or it processes all pixels. It returns
a tuple of the decrypted message and a bool indicating whether the
delimiter (present in all valid messages) was found.
"""
delimiter = False
pixel_list, word_total = [], ""
RGB_binary_list = pixels_to_binary(img)

# Iterates through each pixel's binary values and concatenates the least significant bits into decoded code
for pixel in RGB_binary_list:
output = "0"
r, g, b = pixel[0][-N_PLANES:], pixel[1][-N_PLANES:], pixel[2][-1]
output += f"{b}{g}{r}"
pixel_list.append(int(output, 2))

# Iterates through each binary output and converts each binary to ASCII, simultaneously checking for the delimiter
for binary in pixel_list:
if word_total[-5:] == ",,,..":
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expect ',,,..' to be defined once as a constant, so that you can change the delimiter in one place without having to make any other changes elsewhere in the code base.

You could also have used the str.endswith method.

delimiter = True
break
word_total += format(binary, "c")
return word_total[:-5], delimiter
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise, word_total[:-5] can be rewritten with a call to str.removesuffix, so that the code doesn't depend on a known length for the delimiter. It might look something like word_total.removesuffix(DELIMITER).



def decrypt_image_from_image(image: Image) -> Image:
"""
Decrypts the secret image from the given input image.

This function attempts to read the size data embedded in
a cover image's metadata. Failing that, it decrypts the whole image.
It should recover the four most significant bits of each pixel of the
original image.

:param image: Pillow image containing encrypted image.
:return: The reconstruction of the original image.
"""
if size := parse_exif(image.getexif()):
width, height = size
image = image.crop((0, 0, width, height))
else:
print("WARNING: Could not parse size from EXIF metadata. Falling back to decrypting whole image")

return image.point(lambda byte: (byte & 0b00001111) << BITS_4)
Loading