-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c0548e5
commit 143a21b
Showing
14 changed files
with
396 additions
and
94 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,17 @@ | ||
# myapp/forms.py | ||
from django import forms | ||
|
||
class EncodeForm(forms.Form): | ||
class TextEncodeForm(forms.Form): | ||
message = forms.CharField(widget=forms.Textarea(attrs={'class': 'form-control', 'placeholder': 'Message to hide'})) | ||
cover_image = forms.ImageField(widget=forms.FileInput(attrs={'class': 'form-control'})) | ||
|
||
class FileEncodeForm(forms.Form): | ||
file = forms.FileField(widget=forms.ClearableFileInput(attrs={'class': 'form-control'})) | ||
cover_image = forms.ImageField(widget=forms.FileInput(attrs={'class': 'form-control'})) | ||
|
||
class TextDecodeForm(forms.Form): | ||
stego_image = forms.ImageField(widget=forms.FileInput(attrs={'class': 'form-control'})) | ||
|
||
|
||
class DecodeForm(forms.Form): | ||
class FileDecodeForm(forms.Form): | ||
stego_image = forms.ImageField(widget=forms.FileInput(attrs={'class': 'form-control'})) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
from PIL import Image | ||
|
||
def file_to_binary(file_bytes): | ||
return ''.join(format(byte, '08b') for byte in file_bytes) | ||
|
||
|
||
def binary_to_bytes(binary_data): | ||
byte_data = bytearray(int(binary_data[i:i+8], 2) for i in range(0, len(binary_data), 8)) | ||
return bytes(byte_data) | ||
|
||
|
||
def file_to_bytes(file_path): | ||
with open(file_path, 'rb') as file: | ||
file_bytes = file.read() | ||
return file_bytes | ||
|
||
|
||
def bytes_to_file(file_path, file_bytes): | ||
with open(file_path, 'wb') as file: | ||
file.write(file_bytes) | ||
|
||
|
||
def hide_data_in_image(image_path, file_bytes, output_image_path): | ||
image = Image.open(image_path) | ||
pixels = list(image.getdata()) | ||
|
||
binary_data = file_to_binary(file_bytes) | ||
binary_data += '1111111111111110' # Add a delimiter to signify the end of data | ||
|
||
new_pixels = [] | ||
data_index = 0 | ||
for pixel in pixels: | ||
r, g, b = pixel[:3] | ||
if data_index < len(binary_data): | ||
new_r = (r & ~1) | int(binary_data[data_index]) | ||
data_index += 1 | ||
else: | ||
new_r = r | ||
|
||
if data_index < len(binary_data): | ||
new_g = (g & ~1) | int(binary_data[data_index]) | ||
data_index += 1 | ||
else: | ||
new_g = g | ||
|
||
if data_index < len(binary_data): | ||
new_b = (b & ~1) | int(binary_data[data_index]) | ||
data_index += 1 | ||
else: | ||
new_b = b | ||
|
||
# Maintain the alpha channel if present | ||
if len(pixel) == 4: | ||
new_pixels.append((new_r, new_g, new_b, pixel[3])) | ||
else: | ||
new_pixels.append((new_r, new_g, new_b)) | ||
|
||
new_image = Image.new(image.mode, image.size) | ||
new_image.putdata(new_pixels) | ||
new_image.save(output_image_path) | ||
|
||
|
||
def extract_data_from_image(image_path): | ||
image = Image.open(image_path) | ||
pixels = list(image.getdata()) | ||
|
||
binary_data = "" | ||
for pixel in pixels: | ||
r, g, b = pixel[:3] | ||
binary_data += str(r & 1) | ||
binary_data += str(g & 1) | ||
binary_data += str(b & 1) | ||
|
||
# Find the delimiter and cut the data there | ||
delimiter = '1111111111111110' | ||
end_index = binary_data.find(delimiter) | ||
if end_index != -1: | ||
binary_data = binary_data[:end_index] | ||
|
||
return binary_to_bytes(binary_data) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,83 +0,0 @@ | ||
import os | ||
import uuid | ||
import io | ||
from django.conf import settings | ||
from django.http import Http404, HttpResponse | ||
from django.shortcuts import render | ||
from django.core.files.base import ContentFile | ||
from stegnography.forms import EncodeForm, DecodeForm | ||
from stegano import lsb | ||
from PIL import Image | ||
from django.utils.http import unquote | ||
|
||
def encode_view(request): | ||
if request.method == 'POST': | ||
form = EncodeForm(request.POST, request.FILES) | ||
if form.is_valid(): | ||
# Get the form data | ||
message = form.cleaned_data['message'] | ||
cover_image = form.cleaned_data['cover_image'] | ||
|
||
# Process the image and message | ||
image_file = cover_image.read() | ||
image = Image.open(io.BytesIO(image_file)) | ||
stego_image = lsb.hide(image, message) | ||
|
||
# Save the stego image to an in-memory file | ||
output = io.BytesIO() | ||
stego_image.save(output, format="PNG") | ||
output.seek(0) | ||
|
||
# Generate a unique file name | ||
file_name = f'stego_image_{uuid.uuid4().hex[:6]}.png' | ||
stego_image_file = ContentFile(output.read(), file_name) | ||
|
||
# Save file to media folder | ||
file_path = os.path.join(settings.MEDIA_ROOT, file_name) | ||
os.makedirs(os.path.dirname(file_path), exist_ok=True) | ||
with open(file_path, 'wb') as f: | ||
f.write(stego_image_file.read()) | ||
|
||
# Extract just the file name from the path | ||
file_name_only = os.path.basename(file_path) | ||
|
||
# Pass file_name_only to the context | ||
return render(request, 'encryption/encrypt_result.html', {'stego_image_file_name': file_name_only}) | ||
|
||
else: | ||
form = EncodeForm() | ||
|
||
return render(request, 'encryption/encode.html', {'form': form}) | ||
|
||
def decode_view(request): | ||
decoded_message = None | ||
if request.method == 'POST': | ||
form = DecodeForm(request.POST, request.FILES) | ||
if form.is_valid(): | ||
# Get the uploaded stego image | ||
stego_image = form.cleaned_data['stego_image'] | ||
|
||
# Read the image file into memory | ||
image_file = stego_image.read() | ||
image = Image.open(io.BytesIO(image_file)) | ||
|
||
# Decode the message from the image | ||
decoded_message = lsb.reveal(image) | ||
else: | ||
form = DecodeForm() | ||
|
||
return render(request, 'encryption/decode.html', {'form': form, 'decoded_message': decoded_message}) | ||
|
||
def download_file(request, file_name): | ||
# Construct the file path | ||
file_path = os.path.join(settings.MEDIA_ROOT, file_name) | ||
|
||
# Check if the file exists | ||
if not os.path.exists(file_path): | ||
raise Http404("File does not exist") | ||
|
||
# Open the file | ||
with open(file_path, 'rb') as f: | ||
response = HttpResponse(f.read(), content_type='application/octet-stream') | ||
response['Content-Disposition'] = f'attachment; filename="{unquote(file_name)}"' | ||
return response | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
from stegnography.views.text_encoding import * | ||
from stegnography.views.file_encoding import * |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
import os | ||
import uuid | ||
import io | ||
from django.conf import settings | ||
from django.shortcuts import render | ||
from django.core.files.base import ContentFile | ||
from PIL import Image | ||
from stegnography.forms import FileEncodeForm, FileDecodeForm # Ensure you have this form | ||
|
||
# Utility functions for binary conversion | ||
def file_to_binary(file_bytes): | ||
return ''.join(format(byte, '08b') for byte in file_bytes) | ||
|
||
def binary_to_bytes(binary_data): | ||
byte_data = bytearray(int(binary_data[i:i+8], 2) for i in range(0, len(binary_data), 8)) | ||
return bytes(byte_data) | ||
|
||
def file_encode_view(request): | ||
if request.method == 'POST': | ||
form = FileEncodeForm(request.POST, request.FILES) | ||
if form.is_valid(): | ||
# Get the form data | ||
file = form.cleaned_data['file'] # This should be a file | ||
cover_image = form.cleaned_data['cover_image'] | ||
|
||
# Read file into memory | ||
file_content = file.read() | ||
binary_data = file_to_binary(file_content) | ||
|
||
# Process the image and file content | ||
image_file = cover_image.read() | ||
image = Image.open(io.BytesIO(image_file)) | ||
|
||
# Encode the file content into the image | ||
pixels = list(image.getdata()) | ||
binary_data += '1111111111111110' # Add a delimiter to signify the end of data | ||
|
||
new_pixels = [] | ||
data_index = 0 | ||
settings.LOGGER.critical('processing pixels') | ||
for pixel in pixels: | ||
r, g, b = pixel[:3] | ||
if data_index < len(binary_data): | ||
new_r = (r & ~1) | int(binary_data[data_index]) | ||
data_index += 1 | ||
else: | ||
new_r = r | ||
|
||
if data_index < len(binary_data): | ||
new_g = (g & ~1) | int(binary_data[data_index]) | ||
data_index += 1 | ||
else: | ||
new_g = g | ||
|
||
if data_index < len(binary_data): | ||
new_b = (b & ~1) | int(binary_data[data_index]) | ||
data_index += 1 | ||
else: | ||
new_b = b | ||
|
||
if len(pixel) == 4: | ||
new_pixels.append((new_r, new_g, new_b, pixel[3])) | ||
else: | ||
new_pixels.append((new_r, new_g, new_b)) | ||
|
||
new_image = Image.new(image.mode, image.size) | ||
new_image.putdata(new_pixels) | ||
|
||
# Save the stego image to an in-memory file | ||
output = io.BytesIO() | ||
new_image.save(output, format="PNG") | ||
output.seek(0) | ||
|
||
# Generate a unique file name | ||
file_name = f'stego_image_{uuid.uuid4().hex[:6]}.png' | ||
stego_image_file = ContentFile(output.read(), file_name) | ||
|
||
# Save file to media folder | ||
file_path = os.path.join(settings.MEDIA_ROOT, file_name) | ||
os.makedirs(os.path.dirname(file_path), exist_ok=True) | ||
with open(file_path, 'wb') as f: | ||
f.write(stego_image_file.read()) | ||
|
||
# Pass file_name_only to the context | ||
return render(request, 'encryption/file/encrypt_result.html', {'stego_image_file_name': file_name}) | ||
|
||
else: | ||
form = FileEncodeForm() | ||
|
||
return render(request, 'encryption/file/encode.html', {'form': form}) | ||
|
||
|
||
def file_decode_view(request): | ||
if request.method == 'POST': | ||
form = FileDecodeForm(request.POST, request.FILES) | ||
|
||
if form.is_valid(): | ||
# Get the uploaded stego image | ||
stego_image = form.cleaned_data['stego_image'] | ||
|
||
# Read the image file into memory | ||
image_file = stego_image.read() | ||
image = Image.open(io.BytesIO(image_file)) | ||
|
||
# Decode the message from the image | ||
pixels = list(image.getdata()) | ||
|
||
binary_data = "" | ||
for count ,pixel in enumerate(pixels): | ||
settings.LOGGER.debug(f'processing pixels: {count/len(pixels) * 100:.2f}%') | ||
r, g, b = pixel[:3] | ||
binary_data += str(r & 1) | ||
binary_data += str(g & 1) | ||
binary_data += str(b & 1) | ||
|
||
# Find the delimiter and cut the data there | ||
delimiter = '1111111111111110' | ||
end_index = binary_data.find(delimiter) | ||
if end_index != -1: | ||
binary_data = binary_data[:end_index] | ||
|
||
decoded_file_content = binary_to_bytes(binary_data) | ||
|
||
file_name = 'decoded_file' # Adjust the file extension as needed | ||
|
||
# Save the decoded file to an in-memory file | ||
output = io.BytesIO(decoded_file_content) | ||
content_file = ContentFile(output.read(), file_name) | ||
|
||
# Save file to media folder | ||
file_path = os.path.join(settings.MEDIA_ROOT, file_name) | ||
os.makedirs(os.path.dirname(file_path), exist_ok=True) | ||
with open(file_path, 'wb') as f: | ||
f.write(content_file.read()) | ||
|
||
# Pass file_name to the context | ||
return render(request, 'encryption/file/decode_result.html', {'decoded_file_name': file_name}) | ||
|
||
else: | ||
form = FileDecodeForm() | ||
|
||
return render(request, 'encryption/file/decode.html', {'form': form}) |
Oops, something went wrong.