Cleared all print statements in Modules, Errors are raised instead of print. file_steg works with csv.

Signed-off-by: devoalda <linuxes_mojoworld@aleeas.com>
This commit is contained in:
devoalda 2023-05-31 21:04:18 +08:00
parent 1e50a408d7
commit e49a45493b
5 changed files with 213 additions and 160 deletions

View File

@ -7,7 +7,7 @@ class file_steg:
Initialize the class Initialize the class
:param file: Path to the file to encode or decode :param file: Path to the file to encode or decode
:type file: str :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] :type bit_positions: list[int]
""" """
self.supported_extensions = [ self.supported_extensions = [
@ -15,15 +15,17 @@ class file_steg:
"mp4", "mp4",
"docx", "docx",
"xlsx", "xlsx",
"csv",
"pptx" "pptx"
] ]
if file is None: if file is None:
raise ValueError(f"[-] Error: File path is required") raise ValueError(f"[-] Error: File path is required")
if file.split(".")[-1] not in self.supported_extensions: if file.split(".")[-1] not in self.supported_extensions:
raise ValueError(f"[-] Error: File extension {file.split('.')[-1]} is not supported") 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 [7] # Default is LSB
self.bits_to_hide = [8 - bit_pos for bit_pos in bit_positions] if bit_positions else [1] # Default is LSB
self.delimiter = "LZu30,#" # Delimiter to indicate the end of the secret data self.delimiter = "LZu30,#" # Delimiter to indicate the end of the secret data
def encode(self, secret_data_str: str = "Hello World") -> bytes: def encode(self, secret_data_str: str = "Hello World") -> bytes:
@ -40,9 +42,9 @@ class file_steg:
data = f.read() data = f.read()
# Max Bytes to encode # 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( raise ValueError(
f"[-] Error: Binary Secret data length {len(secret_data_str)} is greater than data length {n_bytes}") 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 data_index = 0
encoded_data = bytearray() encoded_data = bytearray()
print(f"[+] Starting encoding...")
for byte in data: for byte in data:
if data_index >= len(binary_secret_data): if data_index >= len(binary_secret_data):
encoded_data.append(byte) encoded_data.append(byte)
@ -70,7 +71,6 @@ class file_steg:
byte = int("".join(byte), 2) byte = int("".join(byte), 2)
encoded_data.append(byte) encoded_data.append(byte)
print(f"[+] Encoding completed successfully.")
return bytes(encoded_data) return bytes(encoded_data)
def decode(self) -> str: def decode(self) -> str:
@ -83,7 +83,7 @@ class file_steg:
data = f.read() data = f.read()
binary_data = "" binary_data = ""
print(f"[+] Starting decoding...") decoded_data = ""
for byte in data: for byte in data:
# Add byte to binary data # Add byte to binary data
# Convert byte from int to binary string # 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)] all_bytes = [binary_data[i: i + 8] for i in range(0, len(binary_data), 8)]
decoded_data = ""
for byte in all_bytes: for byte in all_bytes:
decoded_data += chr(int(byte, 2)) decoded_data += chr(int(byte, 2))
if decoded_data[-len(self.delimiter):] == self.delimiter: if decoded_data[-len(self.delimiter):] == self.delimiter:
break break
print(f"[+] Decoding completed successfully.")
# Return the decoded data # Return the decoded data
return decoded_data[:-len(self.delimiter)] return decoded_data[:-len(self.delimiter)]
@ -123,31 +121,36 @@ class file_steg:
raise TypeError("Type not supported") 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__": if __name__ == "__main__":
with open("../Txt_Steg/secret_data.txt", "r") as f: main()
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)

View File

@ -3,16 +3,21 @@ import numpy as np
class img_steg: 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 Initialize the class
:param image_name: Name of the image to encode or decode :param image_name: Name of the image to encode or decode
:type image_name: str :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] :type bit_to_hide: list[int]
""" """
self.image_name = image_name if 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) 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==" self.delimiter = "abc-123-a=="
def encode(self, secret_data: str = "Hello World") -> np.ndarray: 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 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 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 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") raise ValueError("[!] Insufficient bytes, need a bigger image or less data")
print("[*] Encoding Data...")
# Convert bit to hide position # Convert bit to hide position
bit_to_hide = self.bit_to_hide
data_index = 0 data_index = 0
binary_secret_data = self.to_bin(secret_data) # Convert data to binary binary_secret_data = self.to_bin(secret_data) # Convert data to binary
data_len = len(binary_secret_data) # size of data to hide 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 row in image:
for pixel in row: for pixel in row:
r, g, b = self.to_bin(pixel) # Convert RGB Values to binary format 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: if data_index < data_len:
r = list(r) r = list(r)
r[bit_pos] = binary_secret_data[ r[bit_pos] = binary_secret_data[
@ -74,8 +72,6 @@ class img_steg:
if data_index >= data_len: if data_index >= data_len:
break break
print(f"[+] Encoding completed")
return image return image
def decode(self) -> str: def decode(self) -> str:
@ -84,23 +80,17 @@ class img_steg:
:return: Decoded Data: String :return: Decoded Data: String
""" """
print("[+] Decoding...")
image = cv2.imread(self.image_name) # read image image = cv2.imread(self.image_name) # read image
binary_data = "" binary_data = ""
bit_to_hide = self.bit_to_hide
print(f"[+] Extracting data from image...")
for row in image: for row in image:
for pixel in row: for pixel in row:
r, g, b = self.to_bin(pixel) 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 += 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 += 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 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 # Split by 8 bits
all_bytes = [binary_data[i: i + 8] for i in range(0, len(binary_data), 8)] all_bytes = [binary_data[i: i + 8] for i in range(0, len(binary_data), 8)]
# Convert from bits to characters # Convert from bits to characters
@ -110,7 +100,6 @@ class img_steg:
if decoded_data[-len(self.delimiter):] == self.delimiter: if decoded_data[-len(self.delimiter):] == self.delimiter:
break break
print(f"[+] Decoding completed")
return decoded_data[:-len(self.delimiter)] return decoded_data[:-len(self.delimiter)]
def to_bin(self, data: str) -> str | list[str]: def to_bin(self, data: str) -> str | list[str]:
@ -131,64 +120,32 @@ class img_steg:
else: else:
raise TypeError("Type not supported") 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(): def main():
raise NotImplementedError("This module is not meant to run by itself")
# Variables # Variables
image_name = "test.bmp" # image_name = "test.bmp"
encoded_image_name = "encoded_image.bmp" # encoded_image_name = "encoded_image.bmp"
secret_data = "" # secret_data = ""
# with open("../Txt_Steg/secret_data.txt", "r") as f: # # with open("../Txt_Steg/secret_data.txt", "r") as f:
# secret_data = f.read() # # secret_data = f.read()
#
# Generate random bit positions to hide data into image for testing # # 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 = np.random.choice(range(1, 9), np.random.randint(1, 9), replace=False)
bit_to_hide = list(bit_to_hide) # bit_to_hide = list(bit_to_hide)
bit_to_hide.sort() # bit_to_hide.sort()
print(f"Bits to hide: {bit_to_hide}") # print(f"Bits to hide: {bit_to_hide}")
#
print("Welcome to Image Steganography") # print("Welcome to Image Steganography")
#
# Encode the data into the image # # Encode the data into the image
encoded_image = img_steg(image_name=image_name, bit_to_hide=bit_to_hide).encode(secret_data) # encoded_image = img_steg(image_name=image_name, bit_to_hide=bit_to_hide).encode(secret_data)
cv2.imwrite(encoded_image_name, encoded_image) # cv2.imwrite(encoded_image_name, encoded_image)
#
# Decode the data from the image # # Decode the data from the image
decoded_data = img_steg(image_name=encoded_image_name, bit_to_hide=bit_to_hide).decode() # decoded_data = img_steg(image_name=encoded_image_name, bit_to_hide=bit_to_hide).decode()
print("Decoded Data:", decoded_data) # print("Decoded Data:", decoded_data)
if __name__ == "__main__": if __name__ == "__main__":
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

View File

@ -2,16 +2,19 @@ import numpy as np
class txt_steg: 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 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 :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] :type bit_to_hide: list[int]
""" """
self.text_file = text_file # PathName of the text file if 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) 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 self.delimiter = "abc-123==" # Delimiter to indicate the end of the secret data
def encode(self, secret_data: str = "Hello World") -> str: def encode(self, secret_data: str = "Hello World") -> str:
@ -20,23 +23,20 @@ class txt_steg:
:param secret_data: String :param secret_data: String
:type secret_data: str :type secret_data: str
""" """
print("[+] Encoding...")
# Read text file # Read text file
if self.text_file != "": with open(self.text_file, "r") as f:
with open(self.text_file, "r") as f: data = f.read()
data = f.read()
else:
raise FileNotFoundError("File not found")
secret_data += self.delimiter # Add delimiter secret_data += self.delimiter # Add delimiter
# Max Bits to encode (1 Character = 8 bits) # 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 # Check if secret data can be encoded into text file
if len(secret_data) * 8 > n_bits: if len(secret_data) * 8 > n_bits:
raise ValueError( 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 data_index = 0
# Convert secret data to binary # Convert secret data to binary
@ -44,7 +44,6 @@ class txt_steg:
encoded_data = "" encoded_data = ""
print(f"[+] Starting encoding...")
# Encode data into text # Encode data into text
for char in data: for char in data:
bin_char = self.to_bin(char) bin_char = self.to_bin(char)
@ -59,7 +58,6 @@ class txt_steg:
data_index += 1 data_index += 1
encoded_data += self.from_bin(''.join(bin_char)) encoded_data += self.from_bin(''.join(bin_char))
print(f"[+] Encoded Successfully!")
return encoded_data return encoded_data
def decode(self) -> str: def decode(self) -> str:
@ -69,23 +67,17 @@ class txt_steg:
Secret text is stored in the bit_to_hide positions Secret text is stored in the bit_to_hide positions
:return: Decoded Data: String :return: Decoded Data: String
""" """
print("[+] Decoding...")
# Read text file and covert to binary # Read text file and covert to binary
if self.text_file != "": with open(self.text_file, "r") as f:
with open(self.text_file, "r") as f: data = f.read()
data = f.read()
else:
raise FileNotFoundError("File not found")
binary_data = "" binary_data = ""
print(f"[+] Gathering data from bit positions: {self.bit_to_hide}")
for char in data: for char in data:
bin_char = self.to_bin(char) bin_char = self.to_bin(char)
bin_char = "0" * (8 - len(bin_char)) + bin_char bin_char = "0" * (8 - len(bin_char)) + bin_char
for bit_pos in self.bit_to_hide: for bit_pos in self.bit_to_hide:
binary_data += bin_char[bit_pos] 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)] all_chars = [binary_data[i:i + 8] for i in range(0, len(binary_data), 8)]
decoded_data = "" decoded_data = ""
@ -94,7 +86,6 @@ class txt_steg:
if decoded_data[-len(self.delimiter):] == self.delimiter: if decoded_data[-len(self.delimiter):] == self.delimiter:
break break
print(f"[+] Decoded Successfully!")
return decoded_data[:-len(self.delimiter)] return decoded_data[:-len(self.delimiter)]
def to_bin(self, data: str) -> str | list[str]: def to_bin(self, data: str) -> str | list[str]:
@ -126,26 +117,27 @@ class txt_steg:
def main(): def main():
print("Welcome to Text Steganography") raise NotImplementedError("This module is not meant to run by itself")
text_file_name = "test.txt" # print("Welcome to Text Steganography")
with open("../Txt_Steg/secret_data.txt", "r") as f: # text_file_name = "test.txt"
secret_data = f.read() # 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) # # Create a unique random number list from 1-8, spanning anywhere from 1-8 bits, for testing purposes
bits_to_hide = list(bits_to_hide) # bits_to_hide = np.random.choice(range(1, 9), np.random.randint(1, 9), replace=False)
bits_to_hide.sort() # bits_to_hide = list(bits_to_hide)
print(f"Bits to hide: {bits_to_hide}") # bits_to_hide.sort()
# print(f"Bits to hide: {bits_to_hide}")
# Encode #
encoded_file_name = "encoded_text.txt" # # Encode
encoded_data = txt_steg(text_file=text_file_name, bit_to_hide=bits_to_hide).encode(secret_data) # encoded_file_name = "encoded_text.txt"
with open(f"{encoded_file_name}", "w") as f: # encoded_data = txt_steg(text_file=text_file_name, bit_to_hide=bits_to_hide).encode(secret_data)
f.write(encoded_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() # # Decode
print(decoded_data) # decoded_data = txt_steg(text_file=encoded_file_name, bit_to_hide=bits_to_hide).decode()
# print(decoded_data)
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -6,14 +6,14 @@ import sys
import wave import wave
import warnings 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 WORKING_PATH = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])), "upload") + os.sep
# Supported file extensions # Supported file extensions
supported_files = { supported_files = {
"txt_files": ["txt", "py", "sql", "html", "css", "js", "php", "c", "cpp", "java", "json", "xml", "yml", "md"], "txt_files": ["txt", "py", "sql", "html", "css", "js", "php", "c", "cpp", "java", "json", "xml", "yml", "md"],
"gen_files": ["mp3", "mp4"], "gen_files": ["mp3", "mp4"],
"doc_files": ["docx", "xlsx", "pptx"], "doc_files": ["docx", "xlsx", "pptx", "csv"],
"wav_files": ["wav"], "wav_files": ["wav"],
"image_files": ["bmp", "png"] "image_files": ["bmp", "png"]
} }

101
Application/upload/test.csv Normal file
View File

@ -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
1 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
2 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
3 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
4 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
5 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
7 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
8 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
9 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
10 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
11 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
12 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
13 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
14 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
15 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
16 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
17 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
18 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
19 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
20 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
21 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
22 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
23 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
24 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
25 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
26 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
27 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
28 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
29 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
30 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
31 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
32 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
33 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
34 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
35 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
36 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
37 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
38 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
39 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
40 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
41 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
42 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
43 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
44 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
45 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
46 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
47 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
48 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
49 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
50 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
51 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
52 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
53 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
54 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
55 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
56 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
57 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
58 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
59 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
60 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
61 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
62 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
63 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
64 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
65 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
66 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
67 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
68 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
69 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
70 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
71 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
72 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
73 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
74 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
75 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
76 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
77 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
78 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
79 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
80 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
81 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
82 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
83 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
84 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
85 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
86 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
87 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
88 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
89 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
90 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
91 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
92 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
93 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
94 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
95 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
96 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
97 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
98 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
99 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
100 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6
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