mirror of
https://github.com/cedricbonhomme/Stegano.git
synced 2025-05-12 09:08:31 +02:00
black + remove unused imports
This commit is contained in:
parent
93de151025
commit
d8fe34e5bc
6 changed files with 179 additions and 117 deletions
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/env python
|
||||
#-*- coding: utf-8 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Stéganô - Stéganô is a basic Python Steganography module.
|
||||
# Copyright (C) 2010-2019 Cédric Bonhomme - https://www.cedricbonhomme.org
|
||||
|
@ -25,13 +25,17 @@ __date__ = "$Date: 2016/05/26 $"
|
|||
__revision__ = "$Date: 2017/01/18 $"
|
||||
__license__ = "GPLv3"
|
||||
|
||||
from PIL import Image
|
||||
|
||||
import piexif
|
||||
from stegano import tools
|
||||
|
||||
|
||||
def hide(input_image_file, img_enc, secret_message = None, secret_file = None, img_format = None):
|
||||
def hide(
|
||||
input_image_file,
|
||||
img_enc,
|
||||
secret_message=None,
|
||||
secret_file=None,
|
||||
img_format=None,
|
||||
):
|
||||
"""Hide a message (string) in an image.
|
||||
"""
|
||||
from zlib import compress
|
||||
|
@ -72,13 +76,13 @@ def reveal(input_image_file):
|
|||
img = tools.open_image(input_image_file)
|
||||
|
||||
try:
|
||||
if img.format in ['JPEG', 'TIFF']:
|
||||
if 'exif' in img.info:
|
||||
exif_dict = piexif.load(img.info.get("exif", b''))
|
||||
if img.format in ["JPEG", "TIFF"]:
|
||||
if "exif" in img.info:
|
||||
exif_dict = piexif.load(img.info.get("exif", b""))
|
||||
description_key = piexif.ImageIFD.ImageDescription
|
||||
encoded_message = exif_dict["0th"][description_key]
|
||||
else:
|
||||
encoded_message = b''
|
||||
encoded_message = b""
|
||||
else:
|
||||
raise ValueError("Given file is neither JPEG nor TIFF.")
|
||||
finally:
|
||||
|
@ -91,41 +95,70 @@ if __name__ == "__main__":
|
|||
# Point of entry in execution mode.
|
||||
# TODO: improve the management of arguments
|
||||
from optparse import OptionParser
|
||||
|
||||
parser = OptionParser(version=__version__)
|
||||
parser.add_option('--hide', action='store_true', default=False,
|
||||
help="Hides a message in an image.")
|
||||
parser.add_option('--reveal', action='store_true', default=False,
|
||||
help="Reveals the message hided in an image.")
|
||||
parser.add_option(
|
||||
"--hide",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Hides a message in an image.",
|
||||
)
|
||||
parser.add_option(
|
||||
"--reveal",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Reveals the message hided in an image.",
|
||||
)
|
||||
# Original image
|
||||
parser.add_option("-i", "--input", dest="input_image_file",
|
||||
help="Input image file.")
|
||||
parser.add_option(
|
||||
"-i", "--input", dest="input_image_file", help="Input image file."
|
||||
)
|
||||
# Image containing the secret
|
||||
parser.add_option("-o", "--output", dest="output_image_file",
|
||||
help="Output image containing the secret.")
|
||||
parser.add_option(
|
||||
"-o",
|
||||
"--output",
|
||||
dest="output_image_file",
|
||||
help="Output image containing the secret.",
|
||||
)
|
||||
|
||||
# Secret raw message to hide
|
||||
parser.add_option("-m", "--secret-message", dest="secret_message",
|
||||
help="Your raw secret message to hide.")
|
||||
parser.add_option(
|
||||
"-m",
|
||||
"--secret-message",
|
||||
dest="secret_message",
|
||||
help="Your raw secret message to hide.",
|
||||
)
|
||||
|
||||
# Secret text file to hide.
|
||||
parser.add_option("-f", "--secret-file", dest="secret_file",
|
||||
help="Your secret text file to hide.")
|
||||
parser.add_option(
|
||||
"-f",
|
||||
"--secret-file",
|
||||
dest="secret_file",
|
||||
help="Your secret text file to hide.",
|
||||
)
|
||||
|
||||
parser.set_defaults(input_image_file = './pictures/Elisha-Cuthbert.jpg',
|
||||
output_image_file = './pictures/Elisha-Cuthbert_enc.jpg',
|
||||
secret_message = '', secret_file = '')
|
||||
parser.set_defaults(
|
||||
input_image_file="./pictures/Elisha-Cuthbert.jpg",
|
||||
output_image_file="./pictures/Elisha-Cuthbert_enc.jpg",
|
||||
secret_message="",
|
||||
secret_file="",
|
||||
)
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
if options.hide:
|
||||
if options.secret_message != "" and options.secret_file == "":
|
||||
hide(input_image_file=options.input_image_file, \
|
||||
img_enc=options.output_image_file, \
|
||||
secret_message=options.secret_message)
|
||||
hide(
|
||||
input_image_file=options.input_image_file,
|
||||
img_enc=options.output_image_file,
|
||||
secret_message=options.secret_message,
|
||||
)
|
||||
elif options.secret_message == "" and options.secret_file != "":
|
||||
hide(input_image_file=options.input_image_file, \
|
||||
img_enc=options.output_image_file, \
|
||||
secret_file=options.secret_file)
|
||||
hide(
|
||||
input_image_file=options.input_image_file,
|
||||
img_enc=options.output_image_file,
|
||||
secret_file=options.secret_file,
|
||||
)
|
||||
|
||||
elif options.reveal:
|
||||
reveal(input_image_file=options.input_image_file)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/env python
|
||||
#-*- coding: utf-8 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Stéganô - Stéganô is a basic Python Steganography module.
|
||||
# Copyright (C) 2010-2019 Cédric Bonhomme - https://www.cedricbonhomme.org
|
||||
|
@ -25,17 +25,17 @@ __date__ = "$Date: 2016/08/04 $"
|
|||
__revision__ = "$Date: 2017/05/04 $"
|
||||
__license__ = "GPLv3"
|
||||
|
||||
import sys
|
||||
|
||||
from PIL import Image
|
||||
from typing import Union, IO
|
||||
from typing import IO, Union
|
||||
|
||||
from stegano import tools
|
||||
|
||||
def hide(input_image: Union[str, IO[bytes]],
|
||||
message: str,
|
||||
encoding: str = 'UTF-8',
|
||||
auto_convert_rgb: bool = False):
|
||||
|
||||
def hide(
|
||||
input_image: Union[str, IO[bytes]],
|
||||
message: str,
|
||||
encoding: str = "UTF-8",
|
||||
auto_convert_rgb: bool = False,
|
||||
):
|
||||
"""Hide a message (string) in an image with the
|
||||
LSB (Least Significant Bit) technique.
|
||||
"""
|
||||
|
@ -44,14 +44,15 @@ def hide(input_image: Union[str, IO[bytes]],
|
|||
|
||||
img = tools.open_image(input_image)
|
||||
|
||||
if img.mode not in ['RGB', 'RGBA']:
|
||||
if img.mode not in ["RGB", "RGBA"]:
|
||||
if not auto_convert_rgb:
|
||||
print('The mode of the image is not RGB. Mode is {}'.\
|
||||
format(img.mode))
|
||||
answer = input('Convert the image to RGB ? [Y / n]\n') or 'Y'
|
||||
if answer.lower() == 'n':
|
||||
raise Exception('Not a RGB image.')
|
||||
img = img.convert('RGB')
|
||||
print(
|
||||
"The mode of the image is not RGB. Mode is {}".format(img.mode)
|
||||
)
|
||||
answer = input("Convert the image to RGB ? [Y / n]\n") or "Y"
|
||||
if answer.lower() == "n":
|
||||
raise Exception("Not a RGB image.")
|
||||
img = img.convert("RGB")
|
||||
|
||||
encoded = img.copy()
|
||||
width, height = img.size
|
||||
|
@ -59,16 +60,19 @@ def hide(input_image: Union[str, IO[bytes]],
|
|||
|
||||
message = str(message_length) + ":" + str(message)
|
||||
message_bits = "".join(tools.a2bits_list(message, encoding))
|
||||
message_bits += '0' * ((3 - (len(message_bits) % 3)) % 3)
|
||||
message_bits += "0" * ((3 - (len(message_bits) % 3)) % 3)
|
||||
|
||||
npixels = width * height
|
||||
len_message_bits = len(message_bits)
|
||||
if len_message_bits > npixels * 3:
|
||||
raise Exception("The message you want to hide is too long: {}". \
|
||||
format(message_length))
|
||||
raise Exception(
|
||||
"The message you want to hide is too long: {}".format(
|
||||
message_length
|
||||
)
|
||||
)
|
||||
for row in range(height):
|
||||
for col in range(width):
|
||||
if index + 3 <= len_message_bits :
|
||||
if index + 3 <= len_message_bits:
|
||||
|
||||
# Get the colour component.
|
||||
pixel = img.getpixel((col, row))
|
||||
|
@ -78,11 +82,11 @@ def hide(input_image: Union[str, IO[bytes]],
|
|||
|
||||
# Change the Least Significant Bit of each colour component.
|
||||
r = tools.setlsb(r, message_bits[index])
|
||||
g = tools.setlsb(g, message_bits[index+1])
|
||||
b = tools.setlsb(b, message_bits[index+2])
|
||||
g = tools.setlsb(g, message_bits[index + 1])
|
||||
b = tools.setlsb(b, message_bits[index + 2])
|
||||
|
||||
# Save the new pixel
|
||||
if img.mode == 'RGBA':
|
||||
if img.mode == "RGBA":
|
||||
encoded.putpixel((col, row), (r, g, b, pixel[3]))
|
||||
else:
|
||||
encoded.putpixel((col, row), (r, g, b))
|
||||
|
@ -93,7 +97,7 @@ def hide(input_image: Union[str, IO[bytes]],
|
|||
return encoded
|
||||
|
||||
|
||||
def reveal(input_image: Union[str, IO[bytes]], encoding='UTF-8'):
|
||||
def reveal(input_image: Union[str, IO[bytes]], encoding="UTF-8"):
|
||||
"""Find a message in an image (with the LSB technique).
|
||||
"""
|
||||
img = tools.open_image(input_image)
|
||||
|
@ -106,20 +110,20 @@ def reveal(input_image: Union[str, IO[bytes]], encoding='UTF-8'):
|
|||
|
||||
# pixel = [r, g, b] or [r,g,b,a]
|
||||
pixel = img.getpixel((col, row))
|
||||
if img.mode == 'RGBA':
|
||||
pixel = pixel[:3] # ignore the alpha
|
||||
if img.mode == "RGBA":
|
||||
pixel = pixel[:3] # ignore the alpha
|
||||
for color in pixel:
|
||||
buff += (color&1)<<(tools.ENCODINGS[encoding]-1 - count)
|
||||
buff += (color & 1) << (tools.ENCODINGS[encoding] - 1 - count)
|
||||
count += 1
|
||||
if count == tools.ENCODINGS[encoding]:
|
||||
bitab.append(chr(buff))
|
||||
buff, count = 0, 0
|
||||
if bitab[-1] == ":" and limit == None:
|
||||
if bitab[-1] == ":" and limit is None:
|
||||
try:
|
||||
limit = int("".join(bitab[:-1]))
|
||||
except:
|
||||
pass
|
||||
|
||||
if len(bitab)-len(str(limit))-1 == limit :
|
||||
if len(bitab) - len(str(limit)) - 1 == limit:
|
||||
img.close()
|
||||
return "".join(bitab)[len(str(limit))+1:]
|
||||
return "".join(bitab)[len(str(limit)) + 1 :]
|
||||
|
|
|
@ -25,9 +25,10 @@ __date__ = "$Date: 2011/12/28 $"
|
|||
__revision__ = "$Date: 2017/03/10 $"
|
||||
__license__ = "GPLv3"
|
||||
|
||||
import math
|
||||
import itertools
|
||||
from typing import Iterator, List, Dict
|
||||
import math
|
||||
from typing import Dict, Iterator, List
|
||||
|
||||
|
||||
def identity() -> Iterator[int]:
|
||||
"""f(x) = x
|
||||
|
@ -37,15 +38,17 @@ def identity() -> Iterator[int]:
|
|||
yield n
|
||||
n += 1
|
||||
|
||||
|
||||
def triangular_numbers() -> Iterator[int]:
|
||||
"""Triangular numbers: a(n) = C(n+1,2) = n(n+1)/2 = 0+1+2+...+n.
|
||||
http://oeis.org/A000217
|
||||
"""
|
||||
n = 0
|
||||
while True:
|
||||
yield (n*(n+1))//2
|
||||
yield (n * (n + 1)) // 2
|
||||
n += 1
|
||||
|
||||
|
||||
def fermat() -> Iterator[int]:
|
||||
"""Generate the n-th Fermat Number.
|
||||
https://oeis.org/A000215
|
||||
|
@ -53,7 +56,8 @@ def fermat() -> Iterator[int]:
|
|||
y = 3
|
||||
while True:
|
||||
yield y
|
||||
y = pow(y-1,2)+1
|
||||
y = pow(y - 1, 2) + 1
|
||||
|
||||
|
||||
def mersenne() -> Iterator[int]:
|
||||
"""Generate 2^p - 1, where p is prime.
|
||||
|
@ -61,13 +65,14 @@ def mersenne() -> Iterator[int]:
|
|||
"""
|
||||
prime_numbers = eratosthenes()
|
||||
while True:
|
||||
yield 2**next(prime_numbers) - 1
|
||||
yield 2 ** next(prime_numbers) - 1
|
||||
|
||||
|
||||
def eratosthenes() -> Iterator[int]:
|
||||
"""Generate the prime numbers with the sieve of Eratosthenes.
|
||||
https://oeis.org/A000040
|
||||
"""
|
||||
d = {} # type: Dict[int, List[int]]
|
||||
d = {} # type: Dict[int, List[int]]
|
||||
for i in itertools.count(2):
|
||||
if i in d:
|
||||
for j in d[i]:
|
||||
|
@ -77,6 +82,7 @@ def eratosthenes() -> Iterator[int]:
|
|||
d[i * i] = [i]
|
||||
yield i
|
||||
|
||||
|
||||
def composite() -> Iterator[int]:
|
||||
"""Generate the composite numbers using the sieve of Eratosthenes.
|
||||
https://oeis.org/A002808
|
||||
|
@ -87,6 +93,7 @@ def composite() -> Iterator[int]:
|
|||
yield n
|
||||
p1 = p2
|
||||
|
||||
|
||||
def carmichael() -> Iterator[int]:
|
||||
"""Composite numbers n such that a^(n-1) == 1 (mod n) for every a coprime
|
||||
to n.
|
||||
|
@ -94,11 +101,12 @@ def carmichael() -> Iterator[int]:
|
|||
"""
|
||||
for m in composite():
|
||||
for a in range(2, m):
|
||||
if pow(a,m,m) != a:
|
||||
if pow(a, m, m) != a:
|
||||
break
|
||||
else:
|
||||
yield m
|
||||
|
||||
|
||||
def ackermann_naive(m: int, n: int) -> int:
|
||||
"""Ackermann number.
|
||||
"""
|
||||
|
@ -109,6 +117,7 @@ def ackermann_naive(m: int, n: int) -> int:
|
|||
else:
|
||||
return ackermann(m - 1, ackermann(m, n - 1))
|
||||
|
||||
|
||||
def ackermann(m: int, n: int) -> int:
|
||||
"""Ackermann number.
|
||||
"""
|
||||
|
@ -127,6 +136,7 @@ def ackermann(m: int, n: int) -> int:
|
|||
else:
|
||||
return n + 1
|
||||
|
||||
|
||||
def fibonacci() -> Iterator[int]:
|
||||
"""Generate the sequence of Fibonacci.
|
||||
https://oeis.org/A000045
|
||||
|
@ -136,6 +146,7 @@ def fibonacci() -> Iterator[int]:
|
|||
yield a
|
||||
a, b = b, a + b
|
||||
|
||||
|
||||
def log_gen() -> Iterator[int]:
|
||||
"""Logarithmic generator.
|
||||
"""
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/env python
|
||||
#-*- coding: utf-8 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Stéganô - Stéganô is a basic Python Steganography module.
|
||||
# Copyright (C) 2010-2019 Cédric Bonhomme - https://www.cedricbonhomme.org
|
||||
|
@ -25,20 +25,21 @@ __date__ = "$Date: 2016/03/13 $"
|
|||
__revision__ = "$Date: 2018/12/18 $"
|
||||
__license__ = "GPLv3"
|
||||
|
||||
import sys
|
||||
from typing import IO, Iterator, Union
|
||||
|
||||
from PIL import Image
|
||||
from typing import Union, Iterator, IO
|
||||
|
||||
from stegano import tools
|
||||
from . import generators
|
||||
|
||||
def hide(input_image: Union[str, IO[bytes]],
|
||||
message: str,
|
||||
generator: Iterator[int],
|
||||
shift: int = 0,
|
||||
encoding: str = 'UTF-8',
|
||||
auto_convert_rgb: bool = False):
|
||||
|
||||
def hide(
|
||||
input_image: Union[str, IO[bytes]],
|
||||
message: str,
|
||||
generator: Iterator[int],
|
||||
shift: int = 0,
|
||||
encoding: str = "UTF-8",
|
||||
auto_convert_rgb: bool = False,
|
||||
):
|
||||
"""Hide a message (string) in an image with the
|
||||
LSB (Least Significant Bit) technique.
|
||||
"""
|
||||
|
@ -47,14 +48,15 @@ def hide(input_image: Union[str, IO[bytes]],
|
|||
|
||||
img = tools.open_image(input_image)
|
||||
|
||||
if img.mode not in ['RGB', 'RGBA']:
|
||||
if img.mode not in ["RGB", "RGBA"]:
|
||||
if not auto_convert_rgb:
|
||||
print('The mode of the image is not RGB. Mode is {}'.\
|
||||
format(img.mode))
|
||||
answer = input('Convert the image to RGB ? [Y / n]\n') or 'Y'
|
||||
if answer.lower() == 'n':
|
||||
raise Exception('Not a RGB image.')
|
||||
img = img.convert('RGB')
|
||||
print(
|
||||
"The mode of the image is not RGB. Mode is {}".format(img.mode)
|
||||
)
|
||||
answer = input("Convert the image to RGB ? [Y / n]\n") or "Y"
|
||||
if answer.lower() == "n":
|
||||
raise Exception("Not a RGB image.")
|
||||
img = img.convert("RGB")
|
||||
|
||||
img_list = list(img.getdata())
|
||||
width, height = img.size
|
||||
|
@ -62,36 +64,39 @@ def hide(input_image: Union[str, IO[bytes]],
|
|||
|
||||
message = str(message_length) + ":" + str(message)
|
||||
message_bits = "".join(tools.a2bits_list(message, encoding))
|
||||
message_bits += '0' * ((3 - (len(message_bits) % 3)) % 3)
|
||||
message_bits += "0" * ((3 - (len(message_bits) % 3)) % 3)
|
||||
|
||||
npixels = width * height
|
||||
len_message_bits = len(message_bits)
|
||||
if len_message_bits > npixels * 3:
|
||||
raise Exception("The message you want to hide is too long: {}". \
|
||||
format(message_length))
|
||||
raise Exception(
|
||||
"The message you want to hide is too long: {}".format(
|
||||
message_length
|
||||
)
|
||||
)
|
||||
while shift != 0:
|
||||
next(generator)
|
||||
shift -= 1
|
||||
|
||||
while index + 3 <= len_message_bits :
|
||||
while index + 3 <= len_message_bits:
|
||||
generated_number = next(generator)
|
||||
r, g, b, *a = img_list[generated_number]
|
||||
|
||||
# Change the Least Significant Bit of each colour component.
|
||||
r = tools.setlsb(r, message_bits[index])
|
||||
g = tools.setlsb(g, message_bits[index+1])
|
||||
b = tools.setlsb(b, message_bits[index+2])
|
||||
g = tools.setlsb(g, message_bits[index + 1])
|
||||
b = tools.setlsb(b, message_bits[index + 2])
|
||||
|
||||
# Save the new pixel
|
||||
if img.mode == 'RGBA':
|
||||
img_list[generated_number] = (r, g , b, a[0])
|
||||
if img.mode == "RGBA":
|
||||
img_list[generated_number] = (r, g, b, a[0])
|
||||
else:
|
||||
img_list[generated_number] = (r, g , b)
|
||||
img_list[generated_number] = (r, g, b)
|
||||
|
||||
index += 3
|
||||
|
||||
# create empty new image of appropriate format
|
||||
encoded = Image.new('RGB', (img.size))
|
||||
encoded = Image.new("RGB", (img.size))
|
||||
|
||||
# insert saved data into the image
|
||||
encoded.putdata(img_list)
|
||||
|
@ -99,10 +104,12 @@ def hide(input_image: Union[str, IO[bytes]],
|
|||
return encoded
|
||||
|
||||
|
||||
def reveal(input_image: Union[str, IO[bytes]],
|
||||
generator: Iterator[int],
|
||||
shift: int = 0,
|
||||
encoding: str = 'UTF-8'):
|
||||
def reveal(
|
||||
input_image: Union[str, IO[bytes]],
|
||||
generator: Iterator[int],
|
||||
shift: int = 0,
|
||||
encoding: str = "UTF-8",
|
||||
):
|
||||
"""Find a message in an image (with the LSB technique).
|
||||
"""
|
||||
img = tools.open_image(input_image)
|
||||
|
@ -120,7 +127,7 @@ def reveal(input_image: Union[str, IO[bytes]],
|
|||
generated_number = next(generator)
|
||||
# color = [r, g, b]
|
||||
for color in img_list[generated_number]:
|
||||
buff += (color&1)<<(tools.ENCODINGS[encoding]-1 - count)
|
||||
buff += (color & 1) << (tools.ENCODINGS[encoding] - 1 - count)
|
||||
count += 1
|
||||
if count == tools.ENCODINGS[encoding]:
|
||||
bitab.append(chr(buff))
|
||||
|
@ -130,5 +137,5 @@ def reveal(input_image: Union[str, IO[bytes]],
|
|||
limit = int("".join(bitab[:-1]))
|
||||
else:
|
||||
raise IndexError("Impossible to detect message.")
|
||||
if len(bitab)-len(str(limit))-1 == limit :
|
||||
return "".join(bitab)[len(str(limit))+1:]
|
||||
if len(bitab) - len(str(limit)) - 1 == limit:
|
||||
return "".join(bitab)[len(str(limit)) + 1 :]
|
||||
|
|
|
@ -25,12 +25,11 @@ __date__ = "$Date: 2010/10/01 $"
|
|||
__revision__ = "$Date: 2017/02/06 $"
|
||||
__license__ = "GPLv3"
|
||||
|
||||
import sys
|
||||
from typing import IO, Union
|
||||
|
||||
from PIL import Image
|
||||
from typing import Union, IO
|
||||
from stegano import tools
|
||||
|
||||
|
||||
def hide(input_image: Union[str, IO[bytes]], message: str):
|
||||
"""
|
||||
Hide a message (string) in an image.
|
||||
|
@ -54,15 +53,16 @@ def hide(input_image: Union[str, IO[bytes]], message: str):
|
|||
if row == 0 and col == 0 and index < message_length:
|
||||
asc = message_length
|
||||
elif index <= message_length:
|
||||
c = message[index -1]
|
||||
c = message[index - 1]
|
||||
asc = ord(c)
|
||||
else:
|
||||
asc = r
|
||||
encoded.putpixel((col, row), (asc, g , b))
|
||||
encoded.putpixel((col, row), (asc, g, b))
|
||||
index += 1
|
||||
img.close()
|
||||
return encoded
|
||||
|
||||
|
||||
def reveal(input_image: Union[str, IO[bytes]]):
|
||||
"""
|
||||
Find a message in an image.
|
||||
|
|
|
@ -27,16 +27,13 @@ __license__ = "GPLv3"
|
|||
|
||||
import base64
|
||||
import itertools
|
||||
from typing import List, Iterator, Tuple, Union
|
||||
from functools import reduce
|
||||
from typing import IO, Iterator, List, Tuple, Union
|
||||
|
||||
from PIL import Image
|
||||
|
||||
ENCODINGS = {
|
||||
'UTF-8': 8,
|
||||
'UTF-32LE': 32
|
||||
}
|
||||
ENCODINGS = {"UTF-8": 8, "UTF-32LE": 32}
|
||||
|
||||
|
||||
def a2bits(chars: str) -> str:
|
||||
"""Converts a string to its bits representation as a string of 0's and 1's.
|
||||
|
@ -44,9 +41,12 @@ def a2bits(chars: str) -> str:
|
|||
>>> a2bits("Hello World!")
|
||||
'010010000110010101101100011011000110111100100000010101110110111101110010011011000110010000100001'
|
||||
"""
|
||||
return bin(reduce(lambda x, y : (x<<8)+y, (ord(c) for c in chars), 1))[3:]
|
||||
return bin(reduce(lambda x, y: (x << 8) + y, (ord(c) for c in chars), 1))[
|
||||
3:
|
||||
]
|
||||
|
||||
def a2bits_list(chars: str, encoding: str ='UTF-8') -> List[str]:
|
||||
|
||||
def a2bits_list(chars: str, encoding: str = "UTF-8") -> List[str]:
|
||||
"""Convert a string to its bits representation as a list of 0's and 1's.
|
||||
|
||||
>>> a2bits_list("Hello World!")
|
||||
|
@ -65,20 +65,24 @@ def a2bits_list(chars: str, encoding: str ='UTF-8') -> List[str]:
|
|||
>>> "".join(a2bits_list("Hello World!"))
|
||||
'010010000110010101101100011011000110111100100000010101110110111101110010011011000110010000100001'
|
||||
"""
|
||||
return [bin(ord(x))[2:].rjust(ENCODINGS[encoding],"0") for x in chars]
|
||||
return [bin(ord(x))[2:].rjust(ENCODINGS[encoding], "0") for x in chars]
|
||||
|
||||
|
||||
def bs(s: int) -> str:
|
||||
"""Converts an int to its bits representation as a string of 0's and 1's.
|
||||
"""
|
||||
return str(s) if s<=1 else bs(s>>1) + str(s&1)
|
||||
return str(s) if s <= 1 else bs(s >> 1) + str(s & 1)
|
||||
|
||||
|
||||
def setlsb(component: int, bit: str) -> int:
|
||||
"""Set Least Significant Bit of a colour component.
|
||||
"""
|
||||
return component & ~1 | int(bit)
|
||||
|
||||
def n_at_a_time(items: List[int], n: int, fillvalue: str) \
|
||||
-> Iterator[Tuple[Union[int, str]]]:
|
||||
|
||||
def n_at_a_time(
|
||||
items: List[int], n: int, fillvalue: str
|
||||
) -> Iterator[Tuple[Union[int, str]]]:
|
||||
"""Returns an iterator which groups n items at a time.
|
||||
Any final partial tuple will be padded with the fillvalue
|
||||
|
||||
|
@ -88,6 +92,7 @@ def n_at_a_time(items: List[int], n: int, fillvalue: str) \
|
|||
it = iter(items)
|
||||
return itertools.zip_longest(*[it] * n, fillvalue=fillvalue)
|
||||
|
||||
|
||||
def binary2base64(binary_file: str) -> str:
|
||||
"""Convert a binary file (OGG, executable, etc.) to a
|
||||
printable string.
|
||||
|
@ -97,12 +102,14 @@ def binary2base64(binary_file: str) -> str:
|
|||
encoded_string = base64.b64encode(bin_file.read())
|
||||
return encoded_string.decode()
|
||||
|
||||
|
||||
def base642binary(b64_fname: str) -> bytes:
|
||||
"""Convert a printable string to a binary file.
|
||||
"""
|
||||
b64_fname += '==='
|
||||
b64_fname += "==="
|
||||
return base64.b64decode(b64_fname)
|
||||
|
||||
|
||||
def open_image(fname_or_instance: Union[str, IO[bytes]]):
|
||||
"""Opens a Image and returns it.
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue