If you’re unsure of the shift value the following script will find that for you. If you already know it’s a ROT 13, simply run the following Bash one liner:

cat cipher.txt | tr '[a-z]' '[n-za-m]' | tr '[A-Z]' '[N-ZA-M]'
Bash
#! /bin/python3
import argparse,enchant
def check_range(value):
value = int(value)
if value >= 26 or value <= 0:
msg = "Shift value must be in the range 1 - 25."
raise argparse.ArgumentTypeError(msg)
return value
def main():
parser = argparse.ArgumentParser(description="""
Entering text surrounded by quotation marks by itself will attempt to decrypt and find
the shift in the supplied encrypted text.
""")
group = parser.add_mutually_exclusive_group()
group.add_argument(dest='encrypted_text', type=str, nargs='?', help="Encrypted text without flag")
group.add_argument('-d', dest='decrypt', type=str, nargs='?', help="Decrypt the supplied text")
group.add_argument('-e', dest='encrypt', type=str, nargs='?', help="Encrypt the supplied text")
parser.add_argument('-s', dest='shift', nargs='?', type=check_range, help="""
The number of characters to shift. Value must be between 1 and 25
""")
args = parser.parse_args()
if args.encrypt:
if args.shift:
shift = args.shift
else:
shift = 13
print(encrypt(args.encrypt, shift))
elif args.decrypt:
if(args.shift):
print(decrypt(args.decrypt,args.shift))
else:
find_shift(args.decrypt)
elif args.shift and args.encrypted_text:
print(decrypt(args.encrypted_text,args.shift))
elif args.encrypted_text:
find_shift(args.encrypted_text)
def shift_char(c, shift):
if ord('a') <= ord(c) <= ord('z'):
shift_c = chr(((ord(c) + shift - ord('a')) % 26) + ord('a'))
else:
shift_c = chr(((ord(c) + shift - ord('A')) % 26) + ord('A'))
return shift_c
def find_shift(encrypted_text, start=1, end=27):
shift_list = []
for i in range(start,end):
decrypted = decrypt(encrypted_text, i)
shift_list.append(decrypted)
print("position: %d \t %s"%(i,decrypted))
eng_dictionary = enchant.Dict("en_US")
match = ""
for i,shift_str in enumerate(shift_list):
#check for min of three real words to consider it a match
hits = 0
for word in shift_str.split(" "):
if(eng_dictionary.check(word) == True):
if(hits == 3):
match = shift_str
break
else:
hits += 1
if(len(match)):
print("\n\nMatch at shift position %d: %s"%(i+1,match))
break
if(not len(match)):
print("\n\nNo match found.")
return(shift_list)
def decrypt(encrypted_text, shift_int):
new_string = ''
for char in encrypted_text:
if char.isalpha():
new_string += shift_char(char, shift_int)
else:
new_string += char
return new_string
def encrypt(unencrypted_text, shift_int):
new_string = ''
for char in unencrypted_text:
if (not char.isalpha()):
new_string += char
else:
char_pos = ord(char)
if ord('a') < char_pos <= ord('z'):
shift_c = char_pos - shift_int
if shift_c < ord('a'):
shift_c = ord('z') - (ord('a') - shift_c - 1)
else:
shift_c = char_pos - shift_int
if shift_c < ord('A'):
shift_c = ord('Z') - (ord('A') - shift_c - 1)
new_string += chr(shift_c)
return new_string
if __name__ == "__main__":
main()