Coming 1.1.1-rc

This commit is contained in:
Joshua | Tommaso
2023-11-16 22:26:54 +01:00
parent 85bd85b051
commit 16aafcf625
2 changed files with 328 additions and 154 deletions

59
CHANGELOG.md Normal file
View File

@@ -0,0 +1,59 @@
# Changelog Template
## Release Notes - Version X.X.X
### Summary
Brief overview of the key changes and improvements in this release.
---
### Features
- **Feature 1:** Description of feature 1.
- ...
- **Feature N:** Description of feature N.
### Enhancements
- **Enhancement 1:** Description of enhancement 1.
- ..
- **Enhancement N:** Description of enhancement N.
### Bug Fixes
- **Bug Fix 1:** Description of bug fix 1.
- ...
- **Bug Fix N:** Description of bug fix N.
### Dependencies
List any new dependencies or updates to existing dependencies.
### Breaking Changes
List any changes that could potentially break existing functionality. It's important to highlight these so that users can take proper action.
### Usage
Update any usage instructions or provide information on new features.
### Known Issues
List any known issues that were not addressed in this release.
### Contributors
Acknowledge and credit contributors who contributed to this release.
### Changelog
Provide a detailed changelog with commit references or links.
### Support
Provide information on how users can get support or report issues.
---
Remove the sections that are not applicable to your changes and the [first line](#changelog-template)

View File

@@ -2,6 +2,7 @@ import os
import io
import sys
import argparse
import logging
import numpy as np
@@ -14,6 +15,8 @@ from utils import *
SINGLE_RGB_BIT_SIZE = 8 # Each RGB value is composed of 3 colors, each color is composed of 8 bits
SINGLE_RGB_PIXEL_BIT_SIZE = SINGLE_RGB_BIT_SIZE * 3 # Each pixel is composed of 3 RGB values, each RGB value is composed of 3 colors, each color is composed of 8 bits
__version__ = "1.1.1-rc"
def add_header(image: str, extension: str, data_length: int, output_directory: str = None) -> None:
"""
Adds a header to the cover image before hiding data.
@@ -381,165 +384,277 @@ def differentiate_image(source, cover, output_directory: str = None) -> None:
def main():
init(autoreset=True)
os.system('cls' if os.name == 'nt' else 'clear') # Clear the terminal
os.system('cls' if os.name == 'nt' else 'clear')
print(
"""
,-.-. ,---. .-._ _,---. _,.---._ .-._ _,.---._ _,---. ,---. _ __ ,--.-,,-,--, ,-.-. ,-----.--. _.---.,_ _.---.,_
,--.-./=/ ,/.--.' \ /==/ \ .-._ _.='.'-, \ ,-.' , - `. /==/ \ .-._ ,-.' , - `. _.='.'-, \ .-.,.---. .--.' \ .-`.' ,`./==/ /|=| |,--.-. .-,--. ,--.-./=/ ,//` ` - /==/ .' - , `.-, .' - , `.-,
/==/, ||=| -|\==\-/\ \ |==|, \/ /, /==.'- / /==/_, , - \|==|, \/ /, /==/_, , - \ /==.'- / /==/ ` \ \==\-/\ \ /==/, - \==|_ ||=|, /==/- / /=/_ / /==/, ||=| -|`-'-. -|==| / - , ,_\==\ / - , ,_\==\
\==\, \ / ,|/==/-|_\ | |==|- \| /==/ - .-' |==| .=. |==|- \| |==| .=. /==/ - .-' |==|-, .=., |/==/-|_\ | |==| _ .=. |==| ,|/=| _\==\, \/=/. / \==\, \ / ,| | `|==| | .=. |==| | .=. |==|
\==\ - ' - /\==\, - \ |==| , | -|==|_ /_,-.|==|_ : ;=: - |==| , | -|==|_ : ;=: - |==|_ /_,-.|==| '=' /\==\, - \ |==| , '=',|==|- `-' _ |\==\ \/ -/ \==\ - ' - / | -|==| | - :=; : _|==| | - :=; : _|==|
\==\ , | /==/ - ,| |==| - _ |==| , \_.' )==| , '=' |==| - _ |==| , '=' |==| , \_.' )==|- , .' /==/ - ,| |==|- '..'|==| _ | |==| ,_/ \==\ , | | `|==| | `=` , |==| | `=` , |==|
|==| - ,//==/- /\ - \|==| /\ , \==\- , ( \==\ - ,_ /|==| /\ , |\==\ - ,_ /\==\- , (|==|_ . ,'./==/- /\ - \|==|, | |==| .-. ,\ \==\-, / |==| - ,/ .-','|==| .=.\ _, - /==/.=.\ _, - /==/
\==\ _ / \==\ _.\=\.-'/==/, | |- |/==/ _ , / '.='. - .' /==/, | |- | '.='. - .' /==/ _ , //==/ /\ , )==\ _.\=\.-'/==/ - | /==/, //=/ | /==/._/ \==\ _ / / \==\:=; :`. - .`=.`:=; :`. - .`=.`
`--`--' `--` `--`./ `--``--`------' `--`--'' `--`./ `--` `--`--'' `--`------' `--`-`--`--' `--` `--`---' `--`-' `-`--` `--`-` `--`--' `-----`---``=` ``--'--' `=` ``--'--'
"""
)
print()
print(Fore.YELLOW + "Version 1.0.0")
print("Welcome to VanGonography! Please select an option:")
print()
print(Fore.LIGHTRED_EX + "[1] " + Fore.WHITE + "Hide a file in an image")
print(Fore.LIGHTRED_EX + "[2] " + Fore.WHITE + "Reveal a hidden file in an image")
print(Fore.LIGHTRED_EX + "[3] " + Fore.WHITE + "Show the difference between two images")
print(Fore.LIGHTRED_EX + "[4] " + Fore.WHITE + "Exit")
print()
# Argument parser
parser = argparse.ArgumentParser(description="Van Gonography is a steganography tool that hides files in images.")
while True:
choice = input("Enter your choice: ")
# Optional arguments
optional_group = parser.add_argument_group('Optional arguments')
optional_group.add_argument("-ood", dest="ood", action="store_true", default=False, help="Open file after decoding from image (default: False)")
optional_group.add_argument("-l", "--log", dest="log", type=str, default=False, metavar="LOG_FILE", help="Log file for the program (default: False)")
optional_group.add_argument("-cli", dest="cli", action="store_true", default=False, help="Run the program in CLI mode, this means there's not gonna be any menu (default: False)")
optional_group.add_argument("-o", "--output", dest="output", type=str, metavar="OUTPUT_DIR", help="Output directory for the modified image or revealed file")
optional_group.add_argument("-v", "--version", action="version", version=f"VanGonography v{__version__}", help="Show the version number and exit")
# Positional arguments group (only used in CLI mode)
positional_group = parser.add_argument_group('Positional arguments (only used in CLI mode)')
positional_group.add_argument("-s", "--show", dest="show", action="store_true", default=False, help="Show the difference between two images (default: False)")
positional_group.add_argument("-e", "--encode", dest="encode", action="store_true", default=False, help="Encode the file in the image (default: False)")
positional_group.add_argument("-d", "--decode", dest="decode", action="store_true", default=False, help="Decode the file hidden in the image (default: False)")
positional_group.add_argument("-c", "--cover", dest="cover", type=str, metavar="COVER_IMAGE", help="Image to be used for hiding or revealing, positional only when using decoding, encoding or differentiate")
positional_group.add_argument("-f", "--file", dest="file", type=str, metavar="HIDDEN_FILE", help="File to be hidden")
args = parser.parse_args()
# Checking for CLI mode
if args.cli:
# Logging setup
if args.log:
# If the user wants to log, we will create the log.log file
if args.log == True:
args.log = "log.log"
logging.basicConfig(
filename=args.log,
level=logging.DEBUG,
format="%(asctime)s - %(levelname)s - %(message)s",
datefmt="%Y-%m-%d %H:%M:%S"
)
logging.info("Logging started")
logging.info(f"Arguments: {args}")
if choice == "1":
try:
# Get the file to hide
root = Tk()
root.withdraw()
file = filedialog.askopenfilename(title="Select file to hide")
# Check if the user canceled the file selection
if not file:
print("File selection canceled.")
# Get the cover image
root = Tk()
root.withdraw()
image = filedialog.askopenfilename(title="Select cover image")
# Check if the user canceled the image selection
if not image:
print("Image selection canceled.")
# Check if the selected file is an image
if not is_image_file(image):
print("Selected cover image is not a valid image file.")
# Get the output directory
root = Tk()
root.withdraw()
output_directory = filedialog.askdirectory(title="Select output directory")
# Check if the user canceled the output directory selection
if not output_directory:
print("Output directory selection canceled.")
# Check if the selected output directory is valid
if not os.path.isdir(output_directory):
print("Selected output directory is not a valid directory.")
# Hide the file in the cover image
encode_image(file, image, output_directory)
except Exception as e:
print(f"An error occurred: {e}")
elif choice == "2":
try:
# Get the image with the hidden file
root = Tk()
root.withdraw()
image = filedialog.askopenfilename(title="Select image with hidden file")
# Check if the user canceled the image selection
if not image:
print("Image selection canceled.")
# Check if the selected file is an image
if not is_image_file(image):
print("Selected image is not a valid image file.")
# Get the output directory
root = Tk()
root.withdraw()
output_directory = filedialog.askdirectory(title="Select output directory")
# Check if the user canceled the output directory selection
if not output_directory:
print("Output directory selection canceled.")
# Check if the selected output directory is valid
if not os.path.isdir(output_directory):
print("Selected output directory is not a valid directory.")
# Reveal the hidden file
decode_image(image, output_directory)
except Exception as e:
print(f"An error occurred: {e}")
elif choice == "3":
try:
# Get the source image
root = Tk()
root.withdraw()
source = filedialog.askopenfilename(title="Select source image")
# Check if the user canceled the image selection
if not source:
print("Source image selection canceled.")
# Check if the selected file is an image
if not is_image_file(source):
print("Selected source image is not a valid image file.")
# Get the cover image
root = Tk()
root.withdraw()
cover = filedialog.askopenfilename(title="Select cover image")
# Check if the user canceled the image selection
if not cover:
print("Cover image selection canceled.")
# Check if the selected file is an image
if not is_image_file(cover):
print("Selected cover image is not a valid image file.")
# Get the output directory
root = Tk()
root.withdraw()
output_directory = filedialog.askdirectory(title="Select output directory")
# Check if the user canceled the output directory selection
if not output_directory:
print("Output directory selection canceled.")
# Check if the selected output directory is valid
if not os.path.isdir(output_directory):
print("Selected output directory is not a valid directory.")
# Show the difference between the source and cover images
differentiate_image(source, cover, output_directory)
except Exception as e:
print(f"An error occurred: {e}")
elif choice == "4":
print("Exiting...")
# CLI mode starts here
if args.cover: # Checking if a cover image is given (essential for both decoding and encoding)
# Is the user choosing to encode or decode?
if args.encode: # Encode
# Checking if a file to hide is given
if not args.file:
print("You must insert the file to hide")
logging.error("No file to hide was given")
return
try:
logging.info("Encoding started") # Logging the start
logging.info(f"Encoding {args.file} in {args.cover}") # Logging the file and cover image
encode_image(args.file, args.cover, args.output)
print(f"File hidden successfully in {args.cover}.")
logging.info(f"File hidden successfully in {args.cover}.") # Logging the success message, this is also useful for checking the time it took to hide the file
except Exception as e:
print(f"An error occurred: {e}")
logging.error(f"An error occurred: {e}")
# Checking for decode
elif args.decode:
if args.file:
print("You can't insert the file you must only insert the image with the hidden file and optionally the output directory.")
logging.error("A file to hide was given, but you must only insert the image with the hidden file and optionally the output directory.")
try:
logging.info("Decoding started") # Logging the start
logging.info(f"Decoding {args.cover}") # Logging the cover image
decode_image(args.cover, args.output, args.ood)
print(f"File revealed successfully from {args.cover}.")
logging.info(f"File revealed successfully from {args.cover}.") # Same as above
except Exception as e:
print(f"An error occurred: {e}")
logging.error(f"An error occurred: {e}")
# Checking for differentiating images
elif args.show:
if args.file:
print("You can't insert the file to hide you must only insert the source and cover images and optionally the output directory.")
logging.error("A file to hide was given, but you must only insert the source and cover images and optionally the output directory.")
try:
logging.info("Differentiating started") # Logging the start
logging.info(f"Differentiating {args.cover} and {args.file}") # Logging the source and cover images
differentiate_image(args.cover, args.output)
print(f"Difference image saved successfully as Difference.png.")
logging.info(f"Difference image saved successfully as Difference.png.") # Again, same as above
except Exception as e:
print(f"An error occurred: {e}")
logging.error(f"An error occurred: {e}")
# Something's wrong
else:
print("Invalid arguments.")
logging.error("Invalid arguments, you must choose a mode to run the program in between encode, decode and show.")
else:
print("You must insert all the required arguments, no cover image was given, use -h for help.")
logging.error("No cover image was given, for checking all the arguments use -h in CLI mode.")
# Using UI mode if no arguments are given
else:
# Checking if any arguments are given
if args.show or args.encode or args.decode or args.output or args.cover or args.file:
print("You can't use arguments in UI mode.")
return
else:
print("Invalid choice.")
# UI mode
init(autoreset=True)
print(
"""
,-.-. ,---. .-._ _,---. _,.---._ .-._ _,.---._ _,---. ,---. _ __ ,--.-,,-,--, ,-.-. ,-----.--. _.---.,_ _.---.,_
,--.-./=/ ,/.--.' \ /==/ \ .-._ _.='.'-, \ ,-.' , - `. /==/ \ .-._ ,-.' , - `. _.='.'-, \ .-.,.---. .--.' \ .-`.' ,`./==/ /|=| |,--.-. .-,--. ,--.-./=/ ,//` ` - /==/ .' - , `.-, .' - , `.-,
/==/, ||=| -|\==\-/\ \ |==|, \/ /, /==.'- / /==/_, , - \|==|, \/ /, /==/_, , - \ /==.'- / /==/ ` \ \==\-/\ \ /==/, - \==|_ ||=|, /==/- / /=/_ / /==/, ||=| -|`-'-. -|==| / - , ,_\==\ / - , ,_\==\
\==\, \ / ,|/==/-|_\ | |==|- \| /==/ - .-' |==| .=. |==|- \| |==| .=. /==/ - .-' |==|-, .=., |/==/-|_\ | |==| _ .=. |==| ,|/=| _\==\, \/=/. / \==\, \ / ,| | `|==| | .=. |==| | .=. |==|
\==\ - ' - /\==\, - \ |==| , | -|==|_ /_,-.|==|_ : ;=: - |==| , | -|==|_ : ;=: - |==|_ /_,-.|==| '=' /\==\, - \ |==| , '=',|==|- `-' _ |\==\ \/ -/ \==\ - ' - / | -|==| | - :=; : _|==| | - :=; : _|==|
\==\ , | /==/ - ,| |==| - _ |==| , \_.' )==| , '=' |==| - _ |==| , '=' |==| , \_.' )==|- , .' /==/ - ,| |==|- '..'|==| _ | |==| ,_/ \==\ , | | `|==| | `=` , |==| | `=` , |==|
|==| - ,//==/- /\ - \|==| /\ , \==\- , ( \==\ - ,_ /|==| /\ , |\==\ - ,_ /\==\- , (|==|_ . ,'./==/- /\ - \|==|, | |==| .-. ,\ \==\-, / |==| - ,/ .-','|==| .=.\ _, - /==/.=.\ _, - /==/
\==\ _ / \==\ _.\=\.-'/==/, | |- |/==/ _ , / '.='. - .' /==/, | |- | '.='. - .' /==/ _ , //==/ /\ , )==\ _.\=\.-'/==/ - | /==/, //=/ | /==/._/ \==\ _ / / \==\:=; :`. - .`=.`:=; :`. - .`=.`
`--`--' `--` `--`./ `--``--`------' `--`--'' `--`./ `--` `--`--'' `--`------' `--`-`--`--' `--` `--`---' `--`-' `-`--` `--`-` `--`--' `-----`---``=` ``--'--' `=` ``--'--'
"""
)
print()
print(Fore.YELLOW + "Version 1.0.0")
print("Welcome to VanGonography! Please select an option:")
print()
print(Fore.LIGHTRED_EX + "[1] " + Fore.WHITE + "Hide a file in an image")
print(Fore.LIGHTRED_EX + "[2] " + Fore.WHITE + "Reveal a hidden file in an image")
print(Fore.LIGHTRED_EX + "[3] " + Fore.WHITE + "Show the difference between two images")
print(Fore.LIGHTRED_EX + "[4] " + Fore.WHITE + "Exit")
print()
while True:
choice = input("Enter your choice: ")
if choice == "1":
try:
# Get the file to hide
root = Tk()
root.withdraw()
file = filedialog.askopenfilename(title="Select file to hide")
# Check if the user canceled the file selection
if not file:
print("File selection canceled.")
# Get the cover image
root = Tk()
root.withdraw()
image = filedialog.askopenfilename(title="Select cover image")
# Check if the user canceled the image selection
if not image:
print("Image selection canceled.")
# Check if the selected file is an image
if not is_image_file(image):
print("Selected cover image is not a valid image file.")
# Get the output directory
root = Tk()
root.withdraw()
output_directory = filedialog.askdirectory(title="Select output directory")
# Check if the user canceled the output directory selection
if not output_directory:
print("Output directory selection canceled.")
# Check if the selected output directory is valid
if not os.path.isdir(output_directory):
print("Selected output directory is not a valid directory.")
# Hide the file in the cover image
encode_image(file, image, output_directory)
except Exception as e:
print(f"An error occurred: {e}")
elif choice == "2":
try:
# Get the image with the hidden file
root = Tk()
root.withdraw()
image = filedialog.askopenfilename(title="Select image with hidden file")
# Check if the user canceled the image selection
if not image:
print("Image selection canceled.")
# Check if the selected file is an image
if not is_image_file(image):
print("Selected image is not a valid image file.")
# Get the output directory
root = Tk()
root.withdraw()
output_directory = filedialog.askdirectory(title="Select output directory")
# Check if the user canceled the output directory selection
if not output_directory:
print("Output directory selection canceled.")
# Check if the selected output directory is valid
if not os.path.isdir(output_directory):
print("Selected output directory is not a valid directory.")
# Reveal the hidden file
decode_image(image, output_directory)
except Exception as e:
print(f"An error occurred: {e}")
elif choice == "3":
try:
# Get the source image
root = Tk()
root.withdraw()
source = filedialog.askopenfilename(title="Select source image")
# Check if the user canceled the image selection
if not source:
print("Source image selection canceled.")
# Check if the selected file is an image
if not is_image_file(source):
print("Selected source image is not a valid image file.")
# Get the cover image
root = Tk()
root.withdraw()
cover = filedialog.askopenfilename(title="Select cover image")
# Check if the user canceled the image selection
if not cover:
print("Cover image selection canceled.")
# Check if the selected file is an image
if not is_image_file(cover):
print("Selected cover image is not a valid image file.")
# Get the output directory
root = Tk()
root.withdraw()
output_directory = filedialog.askdirectory(title="Select output directory")
# Check if the user canceled the output directory selection
if not output_directory:
print("Output directory selection canceled.")
# Check if the selected output directory is valid
if not os.path.isdir(output_directory):
print("Selected output directory is not a valid directory.")
# Show the difference between the source and cover images
differentiate_image(source, cover, output_directory)
except Exception as e:
print(f"An error occurred: {e}")
elif choice == "4":
print("Exiting...")
return
else:
print("Invalid choice.")
if __name__ == '__main__':
main()