From e49a45493b2baf9164c22946c3b0d2b6f2d0b804 Mon Sep 17 00:00:00 2001 From: devoalda Date: Wed, 31 May 2023 21:04:18 +0800 Subject: [PATCH] Cleared all print statements in Modules, Errors are raised instead of print. file_steg works with csv. Signed-off-by: devoalda --- Application/lib/steganography/file_steg.py | 77 +++++++------- Application/lib/steganography/img_steg.py | 111 +++++++-------------- Application/lib/steganography/txt_steg.py | 80 +++++++-------- Application/lsb_rep.py | 4 +- Application/upload/test.csv | 101 +++++++++++++++++++ 5 files changed, 213 insertions(+), 160 deletions(-) create mode 100644 Application/upload/test.csv diff --git a/Application/lib/steganography/file_steg.py b/Application/lib/steganography/file_steg.py index 1e2603b..ad871d7 100644 --- a/Application/lib/steganography/file_steg.py +++ b/Application/lib/steganography/file_steg.py @@ -7,7 +7,7 @@ class file_steg: Initialize the class :param file: Path to the file to encode or decode :type file: str - :param bit_positions: Bit to hide the data in (1 - LSB to 8 - MSB) + :param bit_positions: Bit to hide the data in (1 - LSB to 8 - MSB) Default is LSB (index = 7) :type bit_positions: list[int] """ self.supported_extensions = [ @@ -15,15 +15,17 @@ class file_steg: "mp4", "docx", "xlsx", + "csv", "pptx" ] if file is None: raise ValueError(f"[-] Error: File path is required") if file.split(".")[-1] not in self.supported_extensions: raise ValueError(f"[-] Error: File extension {file.split('.')[-1]} is not supported") + else: + self.file = file - self.file = file - self.bits_to_hide = [8 - bit_pos for bit_pos in bit_positions] if bit_positions else [1] # Default is LSB + self.bits_to_hide = [8 - bit_pos for bit_pos in bit_positions] if bit_positions else [7] # Default is LSB self.delimiter = "LZu30,#" # Delimiter to indicate the end of the secret data def encode(self, secret_data_str: str = "Hello World") -> bytes: @@ -40,9 +42,9 @@ class file_steg: data = f.read() # Max Bytes to encode - n_bytes = len(data) >> 3 + n_bytes = len(data) * 8 * len(self.bits_to_hide) - if len(secret_data_str) > n_bytes: + if len(secret_data_str) * 8 > n_bytes: raise ValueError( f"[-] Error: Binary Secret data length {len(secret_data_str)} is greater than data length {n_bytes}") @@ -55,7 +57,6 @@ class file_steg: data_index = 0 encoded_data = bytearray() - print(f"[+] Starting encoding...") for byte in data: if data_index >= len(binary_secret_data): encoded_data.append(byte) @@ -70,7 +71,6 @@ class file_steg: byte = int("".join(byte), 2) encoded_data.append(byte) - print(f"[+] Encoding completed successfully.") return bytes(encoded_data) def decode(self) -> str: @@ -83,7 +83,7 @@ class file_steg: data = f.read() binary_data = "" - print(f"[+] Starting decoding...") + decoded_data = "" for byte in data: # Add byte to binary data # Convert byte from int to binary string @@ -95,13 +95,11 @@ class file_steg: all_bytes = [binary_data[i: i + 8] for i in range(0, len(binary_data), 8)] - decoded_data = "" for byte in all_bytes: decoded_data += chr(int(byte, 2)) if decoded_data[-len(self.delimiter):] == self.delimiter: break - print(f"[+] Decoding completed successfully.") # Return the decoded data return decoded_data[:-len(self.delimiter)] @@ -123,31 +121,36 @@ class file_steg: raise TypeError("Type not supported") +def main(): + raise NotImplementedError("This module is not meant to run by itself") + # with open("../Txt_Steg/secret_data.txt", "r") as f: + # secret_data = f.read() + # + # bits_to_hide = np.random.choice(range(1, 9), np.random.randint(1, 9), replace=False) + # bits_to_hide = list(bits_to_hide) + # bits_to_hide.sort() + # print(f"Bits to hide: {bits_to_hide}") + # + # mp3_file = "audio.mp3" + # mp4_file = "video.mp4" + # docx_file = "test.docx" + # output_file_mp3 = "encoded_audio.mp3" + # output_file_mp4 = "encoded_video.mp4" + # output_docx_file = "encoded_test.docx" + # + # # Encode data, get as bytes + # encoded_data = file_steg(file=mp3_file, bit_positions=bits_to_hide).encode(secret_data_str=secret_data) + # + # # Write encoded data to file + # with open(output_file_mp3, "wb") as f: + # f.write(encoded_data) + # + # # Decode data from mp3 file + # decoded_data = file_steg(file=output_file_mp3, bit_positions=bits_to_hide).decode() + # + # # Print the decoded data + # print("[+] Decoded data:", decoded_data) + + if __name__ == "__main__": - with open("../Txt_Steg/secret_data.txt", "r") as f: - secret_data = f.read() - - bits_to_hide = np.random.choice(range(1, 9), np.random.randint(1, 9), replace=False) - bits_to_hide = list(bits_to_hide) - bits_to_hide.sort() - print(f"Bits to hide: {bits_to_hide}") - - mp3_file = "audio.mp3" - mp4_file = "video.mp4" - docx_file = "test.docx" - output_file_mp3 = "encoded_audio.mp3" - output_file_mp4 = "encoded_video.mp4" - output_docx_file = "encoded_test.docx" - - # Encode data, get as bytes - encoded_data = file_steg(file=mp3_file, bit_positions=bits_to_hide).encode(secret_data_str=secret_data) - - # Write encoded data to file - with open(output_file_mp3, "wb") as f: - f.write(encoded_data) - - # Decode data from mp3 file - decoded_data = file_steg(file=output_file_mp3, bit_positions=bits_to_hide).decode() - - # Print the decoded data - print("[+] Decoded data:", decoded_data) + main() diff --git a/Application/lib/steganography/img_steg.py b/Application/lib/steganography/img_steg.py index 7b341c2..471bfe3 100644 --- a/Application/lib/steganography/img_steg.py +++ b/Application/lib/steganography/img_steg.py @@ -3,16 +3,21 @@ import numpy as np class img_steg: - def __init__(self, image_name: str = "image.png", bit_to_hide: list[int] = None) -> None: + def __init__(self, image_name: str = None, bit_to_hide: list[int] = None) -> None: """ Initialize the class :param image_name: Name of the image to encode or decode :type image_name: str - :param bit_to_hide: List of bit position to hide the data (LSB is 1, MSB is 8) + :param bit_to_hide: List of bit position to hide the data (LSB is 1, MSB is 8) Default is LSB (index = 7) :type bit_to_hide: list[int] """ - self.image_name = image_name - self.bit_to_hide = [8 - bit_pos for bit_pos in bit_to_hide] if bit_to_hide else [7] # Default is LSB (index = 7) + if image_name: + self.image_name = image_name + else: + raise FileNotFoundError("[!] Please specify an image file") + + self.bit_to_hide = [8 - bit_pos for bit_pos in bit_to_hide] if bit_to_hide else [ + 7] # Default is LSB (index = 7) self.delimiter = "abc-123-a==" def encode(self, secret_data: str = "Hello World") -> np.ndarray: @@ -25,28 +30,21 @@ class img_steg: """ image = cv2.imread(self.image_name) # read image n_bits = (image.shape[0] * image.shape[1] * 3) * 8 * len(self.bit_to_hide) # Max bits to encode - print("[*] Maximum bytes to encode:", n_bits // 8) - print("[*] Maximum bits to encode:", n_bits) secret_data += self.delimiter # Add delimiter at the end of data - if len(secret_data)*8 > n_bits: + if len(secret_data) * 8 > n_bits: raise ValueError("[!] Insufficient bytes, need a bigger image or less data") - print("[*] Encoding Data...") # Convert bit to hide position - bit_to_hide = self.bit_to_hide data_index = 0 binary_secret_data = self.to_bin(secret_data) # Convert data to binary data_len = len(binary_secret_data) # size of data to hide - print(f"[+] Size of data to hide: {data_len} bits") - print("[+] Starting encoding...") - for row in image: for pixel in row: r, g, b = self.to_bin(pixel) # Convert RGB Values to binary format - for bit_pos in bit_to_hide: + for bit_pos in self.bit_to_hide: if data_index < data_len: r = list(r) r[bit_pos] = binary_secret_data[ @@ -74,8 +72,6 @@ class img_steg: if data_index >= data_len: break - print(f"[+] Encoding completed") - return image def decode(self) -> str: @@ -84,23 +80,17 @@ class img_steg: :return: Decoded Data: String """ - print("[+] Decoding...") image = cv2.imread(self.image_name) # read image binary_data = "" - bit_to_hide = self.bit_to_hide - print(f"[+] Extracting data from image...") for row in image: for pixel in row: r, g, b = self.to_bin(pixel) - for bit_pos in bit_to_hide: + for bit_pos in self.bit_to_hide: binary_data += r[bit_pos] # retrieve data from specified bit position of red pixel binary_data += g[bit_pos] # retrieve data from specified bit position of green pixel binary_data += b[bit_pos] # retrieve data from specified bit position of blue pixel - print(f"[+] Forming binary data completed") - print(f"[+] Decoding binary data...") - # Split by 8 bits all_bytes = [binary_data[i: i + 8] for i in range(0, len(binary_data), 8)] # Convert from bits to characters @@ -110,7 +100,6 @@ class img_steg: if decoded_data[-len(self.delimiter):] == self.delimiter: break - print(f"[+] Decoding completed") return decoded_data[:-len(self.delimiter)] def to_bin(self, data: str) -> str | list[str]: @@ -131,64 +120,32 @@ class img_steg: else: raise TypeError("Type not supported") - def from_bin(self, data: str) -> str: - """ - # UNUSED - Convert binary `data` back to the original format - - :param data: Binary Data - :type data: str - :return: Original Data - :rtype: str - """ - return ''.join([chr(int(data[i:i + 8], 2)) for i in range(0, len(data), 8)]) - def main(): + raise NotImplementedError("This module is not meant to run by itself") # Variables - image_name = "test.bmp" - encoded_image_name = "encoded_image.bmp" - secret_data = "" - # with open("../Txt_Steg/secret_data.txt", "r") as f: - # secret_data = f.read() - - # Generate random bit positions to hide data into image for testing - bit_to_hide = np.random.choice(range(1, 9), np.random.randint(1, 9), replace=False) - bit_to_hide = list(bit_to_hide) - bit_to_hide.sort() - print(f"Bits to hide: {bit_to_hide}") - - print("Welcome to Image Steganography") - - # Encode the data into the image - encoded_image = img_steg(image_name=image_name, bit_to_hide=bit_to_hide).encode(secret_data) - cv2.imwrite(encoded_image_name, encoded_image) - - # Decode the data from the image - decoded_data = img_steg(image_name=encoded_image_name, bit_to_hide=bit_to_hide).decode() - print("Decoded Data:", decoded_data) + # image_name = "test.bmp" + # encoded_image_name = "encoded_image.bmp" + # secret_data = "" + # # with open("../Txt_Steg/secret_data.txt", "r") as f: + # # secret_data = f.read() + # + # # Generate random bit positions to hide data into image for testing + # bit_to_hide = np.random.choice(range(1, 9), np.random.randint(1, 9), replace=False) + # bit_to_hide = list(bit_to_hide) + # bit_to_hide.sort() + # print(f"Bits to hide: {bit_to_hide}") + # + # print("Welcome to Image Steganography") + # + # # Encode the data into the image + # encoded_image = img_steg(image_name=image_name, bit_to_hide=bit_to_hide).encode(secret_data) + # cv2.imwrite(encoded_image_name, encoded_image) + # + # # Decode the data from the image + # decoded_data = img_steg(image_name=encoded_image_name, bit_to_hide=bit_to_hide).decode() + # print("Decoded Data:", decoded_data) if __name__ == "__main__": main() - -############################## -# _ _ -# | | | |___ __ _ __ _ ___ -# | | | / __|/ _` |/ _` |/ _ \ -# | |_| \__ \ (_| | (_| | __/ -# \___/|___/\__,_|\__, |\___| -# |___/ -############################## -# -# Initialise class with image name and bit to hide -# -# image_name = image name with extension (String) -# bit_to_hide = [1, 2, 3] (Please Sort the list in ascending order) -# -# To encode: -# encoded_image = img_steg(image_name, bit_to_hide).encode(secret_data) -# -# To decode: -# decoded_data = img_steg(image_name, bit_to_hide).decode() -# Both are string types diff --git a/Application/lib/steganography/txt_steg.py b/Application/lib/steganography/txt_steg.py index 7d5da6b..64028c9 100644 --- a/Application/lib/steganography/txt_steg.py +++ b/Application/lib/steganography/txt_steg.py @@ -2,16 +2,19 @@ import numpy as np class txt_steg: - def __init__(self, text_file: str = "text.txt", bit_to_hide: list[int] = None): + def __init__(self, text_file: str = None, bit_to_hide: list[int] = None) -> None: """ Initialize the class - :param text_file: PathName of the text file to encode or decode + :param text_file: PathName of the text file to encode or decode (Required) :type text_file: str - :param bit_to_hide: Bit to hide the data in (1 - LSB to 8 - MSB) + :param bit_to_hide: Bit to hide the data in (1 - LSB to 8 - MSB), Default is LSB (index = 7) :type bit_to_hide: list[int] """ - self.text_file = text_file # PathName of the text file - self.bit_to_hide = [8 - bit_pos for bit_pos in bit_to_hide] if bit_to_hide else [7] #Each bit value converted to index (e.g. bit 2 -> 6), Default is LSB (index = 7) + if text_file: + self.text_file = text_file + else: + raise FileNotFoundError("Please specify a text file") + self.bit_to_hide = [8 - bit_pos for bit_pos in bit_to_hide] if bit_to_hide else [7] self.delimiter = "abc-123==" # Delimiter to indicate the end of the secret data def encode(self, secret_data: str = "Hello World") -> str: @@ -20,23 +23,20 @@ class txt_steg: :param secret_data: String :type secret_data: str """ - print("[+] Encoding...") # Read text file - if self.text_file != "": - with open(self.text_file, "r") as f: - data = f.read() - else: - raise FileNotFoundError("File not found") + with open(self.text_file, "r") as f: + data = f.read() secret_data += self.delimiter # Add delimiter # Max Bits to encode (1 Character = 8 bits) - n_bits = len(data) * len(self.bit_to_hide) # Bits that can be used (Each character x Number of bits that can be used) + n_bits = len(data) * len( + self.bit_to_hide) # Bits that can be used (Each character x Number of bits that can be used) # Check if secret data can be encoded into text file if len(secret_data) * 8 > n_bits: raise ValueError( - f"[-] Error: Binary Secret data length {len(secret_data)*8} is greater than data length {n_bits}") + f"[-] Error: Binary Secret data length {len(secret_data) * 8} is greater than data length {n_bits}") data_index = 0 # Convert secret data to binary @@ -44,7 +44,6 @@ class txt_steg: encoded_data = "" - print(f"[+] Starting encoding...") # Encode data into text for char in data: bin_char = self.to_bin(char) @@ -59,7 +58,6 @@ class txt_steg: data_index += 1 encoded_data += self.from_bin(''.join(bin_char)) - print(f"[+] Encoded Successfully!") return encoded_data def decode(self) -> str: @@ -69,23 +67,17 @@ class txt_steg: Secret text is stored in the bit_to_hide positions :return: Decoded Data: String """ - print("[+] Decoding...") # Read text file and covert to binary - if self.text_file != "": - with open(self.text_file, "r") as f: - data = f.read() - else: - raise FileNotFoundError("File not found") + with open(self.text_file, "r") as f: + data = f.read() binary_data = "" - print(f"[+] Gathering data from bit positions: {self.bit_to_hide}") for char in data: bin_char = self.to_bin(char) bin_char = "0" * (8 - len(bin_char)) + bin_char for bit_pos in self.bit_to_hide: binary_data += bin_char[bit_pos] - print(f"[+] Converting binary data to text...") all_chars = [binary_data[i:i + 8] for i in range(0, len(binary_data), 8)] decoded_data = "" @@ -94,7 +86,6 @@ class txt_steg: if decoded_data[-len(self.delimiter):] == self.delimiter: break - print(f"[+] Decoded Successfully!") return decoded_data[:-len(self.delimiter)] def to_bin(self, data: str) -> str | list[str]: @@ -126,26 +117,27 @@ class txt_steg: def main(): - print("Welcome to Text Steganography") - text_file_name = "test.txt" - with open("../Txt_Steg/secret_data.txt", "r") as f: - secret_data = f.read() - - # Create a unique random number list from 1-8, spanning anywhere from 1-8 bits, for testing purposes - bits_to_hide = np.random.choice(range(1, 9), np.random.randint(1, 9), replace=False) - bits_to_hide = list(bits_to_hide) - bits_to_hide.sort() - print(f"Bits to hide: {bits_to_hide}") - - # Encode - encoded_file_name = "encoded_text.txt" - encoded_data = txt_steg(text_file=text_file_name, bit_to_hide=bits_to_hide).encode(secret_data) - with open(f"{encoded_file_name}", "w") as f: - f.write(encoded_data) - - # Decode - decoded_data = txt_steg(text_file=encoded_file_name, bit_to_hide=bits_to_hide).decode() - print(decoded_data) + raise NotImplementedError("This module is not meant to run by itself") + # print("Welcome to Text Steganography") + # text_file_name = "test.txt" + # with open("../Txt_Steg/secret_data.txt", "r") as f: + # secret_data = f.read() + # + # # Create a unique random number list from 1-8, spanning anywhere from 1-8 bits, for testing purposes + # bits_to_hide = np.random.choice(range(1, 9), np.random.randint(1, 9), replace=False) + # bits_to_hide = list(bits_to_hide) + # bits_to_hide.sort() + # print(f"Bits to hide: {bits_to_hide}") + # + # # Encode + # encoded_file_name = "encoded_text.txt" + # encoded_data = txt_steg(text_file=text_file_name, bit_to_hide=bits_to_hide).encode(secret_data) + # with open(f"{encoded_file_name}", "w") as f: + # f.write(encoded_data) + # + # # Decode + # decoded_data = txt_steg(text_file=encoded_file_name, bit_to_hide=bits_to_hide).decode() + # print(decoded_data) if __name__ == "__main__": diff --git a/Application/lsb_rep.py b/Application/lsb_rep.py index 7e13d1e..6c4fa80 100644 --- a/Application/lsb_rep.py +++ b/Application/lsb_rep.py @@ -6,14 +6,14 @@ import sys import wave import warnings -MAX_SESSION_SIZE = 4096 * 2 +MAX_SESSION_SIZE = 4096 * 3 WORKING_PATH = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])), "upload") + os.sep # Supported file extensions supported_files = { "txt_files": ["txt", "py", "sql", "html", "css", "js", "php", "c", "cpp", "java", "json", "xml", "yml", "md"], "gen_files": ["mp3", "mp4"], - "doc_files": ["docx", "xlsx", "pptx"], + "doc_files": ["docx", "xlsx", "pptx", "csv"], "wav_files": ["wav"], "image_files": ["bmp", "png"] } diff --git a/Application/upload/test.csv b/Application/upload/test.csv new file mode 100644 index 0000000..67ddfd5 --- /dev/null +++ b/Application/upload/test.csv @@ -0,0 +1,101 @@ + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6 + 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6