steganoCode/stegano.py

144 lines
3.7 KiB
Python
Raw Normal View History

2021-08-16 16:22:18 +02:00
"""
Stegano.py
https://github.com/MatMasIt/steganoCode
2021, Mattia Mascarello
"""
import argparse
import os
import sys
import re
def unicodeToBin(text):
return ''.join('{:08b}'.format(b) for b in text.encode('utf8'))
def binToUnicode(binI):
return bytes(int(b, 2) for b in re.split('(........)', binI) if b).decode('utf8')
def binToRTLLTR(binI):
final = ""
for b in list(binI):
if b == "1":
final += "\u200f" # RTL
else:
final += "\u200e" # LTR
if final[-1] == "\u200f":
final += "\u200e"
else:
final += "\u200f"
return final
def RTLLTRToBin(rtlltr):
final = ""
for c in list(rtlltr):
if c == "\u200f":
final+="1"
else:
final+="0"
final= final [:-1]
return final
def enc(message):
return binToRTLLTR(unicodeToBin(message))
def dec(encoded):
return binToUnicode(RTLLTRToBin(encoded))
def multilineComment(message,comment,begin="\n/*\n",end="\n*/\n"):
final = begin
final += enc(message)
final += "\n"+comment+"\n"
final += end
return final
def srcEnc(src,lang,message,comment):
if lang == "py":
comm = multilineComment(message,comment,'\n"""\n','\n"""\n')+"\n"+src
else:
comm = multilineComment(message,comment)+"\n"+src
return comm
def srcDec(src):
found=[]
accumulator=""
srcPrev=""
for char in list(src):
if char == "\u200f" or char == "\u200e":
accumulator+=char
elif len(accumulator):
accumulator=dec(accumulator)
srcPrev+=accumulator
srcPrev+=char
found.append(accumulator)
accumulator=""
else:
srcPrev+=char
res={"found":found,"cleanedSrc":srcPrev}
return res
parser = argparse.ArgumentParser()
parser.add_argument("--input", help="Input file")
parser.add_argument("--output", help="Output file")
parser.add_argument("--stdin", action='store_true', help="Read from stdin")
parser.add_argument("--stdout", action='store_true', help="Output to stdout")
parser.add_argument("--hide", action='store_true', help="Hide Mode")
parser.add_argument("--showSource", action='store_true', help="Show clean source")
parser.add_argument("--showFound", action='store_true', help="Show Matches")
parser.add_argument("--lang", help="Programming Language")
parser.add_argument("--message", help="Hidden message")
parser.add_argument("--comment", help="Comment")
args = parser.parse_args()
if args.input:
if not os.path.isfile(args.input):
sys.exit("You must specify a valid input file")
try:
data=open(args.input,"r").read()
except:
sys.exit("Could not read file")
elif args.stdin:
data = ""
for line in sys.stdin:
data+=line
else:
sys.exit("No input method")
if not args.output and not args.stdout:
sys.exit("No output method")
if args.hide:
if args.message and len(args.message):
if args.lang:
if args.comment:
comment=args.comment
else:
comment=""
res=srcEnc(data,args.lang,args.message,comment)
if args.output:
out=open(args.output,"w+")
out.write(res)
out.close()
if args.stdout:
print(res)
else:
sys.exit("Specify a language")
else:
sys.exit("Specifify a message")
elif args.showSource or args.showFound:
res=srcDec(data)
if args.showSource:
r=res["cleanedSrc"]
else:
r="\n".join(res["found"])
if args.output:
out=open(args.output,"w+")
out.write(r)
out.close()
if args.stdout:
print(r)
else:
sys.exit("No action specified")