mirror of
https://github.com/tcsenpai/xsacks.git
synced 2025-06-06 11:15:38 +00:00
Initial commit
This commit is contained in:
commit
39c70c6386
98
README.md
Normal file
98
README.md
Normal file
@ -0,0 +1,98 @@
|
||||
# xsacks
|
||||
A crossed substitution alphabetical cipher with secured key
|
||||
|
||||
# The sources
|
||||
|
||||
Please note that the python implementation is still WiP (actually it works but miss some checks and features)
|
||||
|
||||
You can import the xsacks.py module and use xsacks.cipher(msg, key, securekey) and xsacks.decipher(msg, key, securekey).
|
||||
|
||||
If you modify xsacks.py, you can run a cipher-decipher test directly from the module, so to be sure you didn't screw things up.
|
||||
|
||||
# X-SACK
|
||||
|
||||
This cipher is based on crossed substitution of the message and on simple substitution of the key. Let’s explain it with an example.
|
||||
|
||||
Our message is: msg = “Attack now”
|
||||
|
||||
Our key is: key=”secret”
|
||||
|
||||
Our secure-key (you’ll see the meaning later) is: skey=”cryp”
|
||||
|
||||
|
||||
Before starting, you have to assign to each letter of the alphabet (and also to numbers and symbols if you use them) a number. In a software, it could be the ASCII value of the character. Let’s use a simple one as example, though it’s a valid one.
|
||||
|
||||
|
||||
0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ ? .
|
||||
|
||||
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
||||
|
||||
First of all, you need to split msg separating each letter:
|
||||
|
||||
a t t a c k _ n o w
|
||||
|
||||
NOTE: space is a valid character, so i used “_” just to show it
|
||||
|
||||
Now substitute to each letter its number:
|
||||
|
||||
10 29 29 11 13 20 36 23 24 32
|
||||
|
||||
You’ll do the same thing with the key:
|
||||
|
||||
s e c r e t
|
||||
|
||||
28 14 12 27 14 29
|
||||
|
||||
|
||||
Now you have to split the key in two parts:
|
||||
|
||||
|
||||
s e c | r e t
|
||||
|
||||
28 14 12 | 27 14 29
|
||||
|
||||
Time to substitute!
|
||||
|
||||
To perform a cross substition, add to the first msg value the first key value of the first group (a+s), then add to the second msg value the first key value of the second group (t+r), continue adding to the third msg value the second key value of the first group, then to the fourth msg value the second key value of the second group and so on.
|
||||
|
||||
|
||||
Restart from the beginning if the key ends.
|
||||
|
||||
Now you should reconvert numbers to letters. If the number exceed the limit of your alphabet, simple start counting from the beginning.
|
||||
|
||||
Let’s decode:
|
||||
|
||||
10 28 15 34 35 21 36 22 20 18
|
||||
|
||||
A S F Y Z L _ M K I
|
||||
|
||||
The encrypted message is: ASFYZL_MKI
|
||||
|
||||
Though is really hard to decode the message without having the key, even having a large amount of text, the last step is to encode also the key, with the secure key.
|
||||
The steps are almost the same, but you don’t have to split the secure key. Simple substitute, check the values and then reconvert.
|
||||
|
||||
S E C R E T
|
||||
|
||||
28 14 12 27 14 29
|
||||
|
||||
C R Y P C R
|
||||
|
||||
12 27 34 25 12 27 40
|
||||
|
||||
So, the encoded key is: 238EQI
|
||||
|
||||
The only way to decrypt the message is having the msg, the encoded key and the secure key, or the plain key if you are so dumb to give the plain one.
|
||||
|
||||
Give to your friend:
|
||||
|
||||
ASFYZL_MKI
|
||||
|
||||
238EQI
|
||||
|
||||
CRYP
|
||||
|
||||
|
||||
|
||||
And he will be able to read “attack now”.
|
||||
|
||||
|
216
xsacks.py
Normal file
216
xsacks.py
Normal file
@ -0,0 +1,216 @@
|
||||
# How it works
|
||||
|
||||
def cipher(message, key, skey):
|
||||
message = str(message)
|
||||
key = str(key)
|
||||
skey = str(skey)
|
||||
# Needed lists
|
||||
messageCIPHER = []
|
||||
messageCIPHERAscii = []
|
||||
keyCIPHER = []
|
||||
keyCIPHERAscii = []
|
||||
messageASCII = []
|
||||
keyASCII = []
|
||||
keyASCII1 = []
|
||||
keyASCII2 = []
|
||||
skeyASCII = []
|
||||
|
||||
# Divide string in two parts (avoiding generating more than two parts)
|
||||
keyPARTS = []
|
||||
n = int(len(key) / 2)
|
||||
partnumber = 0
|
||||
for i in range(0, len(key), n):
|
||||
partnumber += 1
|
||||
if not partnumber > 2:
|
||||
keyPARTS.append(key[i: i + n])
|
||||
else:
|
||||
keyPARTS[1] = keyPARTS[1] + key[i: i + n]
|
||||
|
||||
# Convert everything in ascii
|
||||
for char in message:
|
||||
messageASCII.append(ord(char))
|
||||
for char in keyPARTS[0]:
|
||||
keyASCII1.append(ord(char))
|
||||
for char in keyPARTS[1]:
|
||||
keyASCII2.append(ord(char))
|
||||
for char in key:
|
||||
keyASCII.append(ord(char))
|
||||
for char in skey:
|
||||
skeyASCII.append(ord(char))
|
||||
|
||||
# Cipher
|
||||
counterEven = 0
|
||||
counterOdd = 0
|
||||
for i in range(0, len(messageASCII)):
|
||||
if (i % 2) == 0:
|
||||
# Use the first part of the key
|
||||
counterEven += 1
|
||||
if counterEven > len(keyASCII1) - 1:
|
||||
counterEven = 0
|
||||
cipherResult = int(messageASCII[i]) + int(keyASCII1[counterEven])
|
||||
while (cipherResult > 125) or (cipherResult < 32):
|
||||
if cipherResult > 125:
|
||||
cipherResult = 31 + (cipherResult - 125)
|
||||
if cipherResult < 32:
|
||||
cipherResult = 126 - (32 - cipherResult)
|
||||
messageCIPHER.append(cipherResult)
|
||||
else:
|
||||
# Use the second part of the key
|
||||
counterOdd += 1
|
||||
if counterOdd > len(keyASCII2) - 1:
|
||||
counterOdd = 0
|
||||
cipherResult = int(messageASCII[i]) + int(keyASCII2[counterOdd])
|
||||
while (cipherResult > 125) or (cipherResult < 32):
|
||||
if cipherResult > 125:
|
||||
cipherResult = 31 + (cipherResult - 125)
|
||||
if cipherResult < 32:
|
||||
cipherResult = 126 - (32 - cipherResult)
|
||||
messageCIPHER.append(cipherResult)
|
||||
|
||||
for char in messageCIPHER:
|
||||
messageCIPHERAscii.append(chr(char))
|
||||
|
||||
# Cipher the key
|
||||
counterSkey = 0
|
||||
for i in range(0, len(keyASCII)):
|
||||
counterSkey += 1
|
||||
if counterSkey > len(skeyASCII) - 1:
|
||||
counterSkey = 0
|
||||
cipherResult = int(keyASCII[i]) + int(skeyASCII[counterSkey])
|
||||
while (cipherResult > 125) or (cipherResult < 32):
|
||||
if cipherResult > 125:
|
||||
cipherResult = 31 + (cipherResult - 125)
|
||||
if cipherResult < 32:
|
||||
cipherResult = 126 - (32 - cipherResult)
|
||||
keyCIPHER.append(cipherResult)
|
||||
|
||||
for char in keyCIPHER:
|
||||
keyCIPHERAscii.append(chr(char))
|
||||
|
||||
# Return a string
|
||||
messageCIPHERstr = ""
|
||||
for i in messageCIPHERAscii:
|
||||
messageCIPHERstr = messageCIPHERstr + i
|
||||
keyCIPHERstr = ""
|
||||
for i in keyCIPHERAscii:
|
||||
keyCIPHERstr = keyCIPHERstr + i
|
||||
|
||||
return messageCIPHERstr, keyCIPHERstr
|
||||
|
||||
|
||||
def decipher(message, key, securekey):
|
||||
message = str(message)
|
||||
key = str(key)
|
||||
securekey = str(securekey)
|
||||
# Needed lists
|
||||
messageCIPHERAscii = []
|
||||
keyCIPHER = []
|
||||
skeyASCII = []
|
||||
keyDECIPHER = []
|
||||
keyDECIPHERChar = []
|
||||
keyDECIPHERParts = []
|
||||
keyDECIPHERParts1 = []
|
||||
keyDECIPHERParts2 = []
|
||||
messageDECIPHERAscii = []
|
||||
messageDECIPHERchar = []
|
||||
|
||||
# Convert everything in ascii
|
||||
for char in message:
|
||||
messageCIPHERAscii.append(ord(char))
|
||||
for char in key:
|
||||
keyCIPHER.append(ord(char))
|
||||
for char in securekey:
|
||||
skeyASCII.append(ord(char))
|
||||
|
||||
# Decipher the key
|
||||
counterSkey = 0
|
||||
for i in range(0, len(keyCIPHER)):
|
||||
counterSkey += 1
|
||||
if counterSkey > len(skeyASCII) - 1:
|
||||
counterSkey = 0
|
||||
cipherResult = int(keyCIPHER[i]) - int(skeyASCII[counterSkey])
|
||||
while (cipherResult > 125) or (cipherResult < 32):
|
||||
if cipherResult > 125:
|
||||
cipherResult = 31 + (cipherResult - 125)
|
||||
if cipherResult < 32:
|
||||
cipherResult = 126 - (32 - cipherResult)
|
||||
keyDECIPHER.append(cipherResult)
|
||||
|
||||
for char in keyDECIPHER:
|
||||
keyDECIPHERChar.append(chr(char))
|
||||
|
||||
# Divide the key deciphered
|
||||
n = int(len(key) / 2)
|
||||
partnumber = 0
|
||||
for i in range(0, len(keyDECIPHERChar), n):
|
||||
partnumber += 1
|
||||
if not partnumber > 2:
|
||||
keyDECIPHERParts.append(keyDECIPHERChar[i: i + n])
|
||||
else:
|
||||
keyDECIPHERParts[1] = keyDECIPHERParts[1] + keyDECIPHERChar[i: i + n]
|
||||
# Convert it to ascii
|
||||
for char in keyDECIPHERParts[0]:
|
||||
keyDECIPHERParts1.append(ord(char))
|
||||
for char in keyDECIPHERParts[1]:
|
||||
keyDECIPHERParts2.append(ord(char))
|
||||
# Copy the functions to cipher but to decipher
|
||||
counterEven = 0
|
||||
counterOdd = 0
|
||||
for i in range(0, len(messageCIPHERAscii)):
|
||||
if (i % 2) == 0:
|
||||
# Use the first part of the key
|
||||
counterEven += 1
|
||||
if counterEven > len(keyDECIPHERParts1) - 1:
|
||||
counterEven = 0
|
||||
cipherResult = int(messageCIPHERAscii[i]) - int(keyDECIPHERParts1[counterEven])
|
||||
while (cipherResult > 125) or (cipherResult < 32):
|
||||
if cipherResult > 125:
|
||||
cipherResult = 31 + (cipherResult - 125)
|
||||
if cipherResult < 32:
|
||||
cipherResult = 126 - (32 - cipherResult)
|
||||
messageDECIPHERAscii.append(cipherResult)
|
||||
else:
|
||||
# Use the second part of the key
|
||||
counterOdd += 1
|
||||
if counterOdd > len(keyDECIPHERParts2) - 1:
|
||||
counterOdd = 0
|
||||
cipherResult = int(messageCIPHERAscii[i]) - int(keyDECIPHERParts2[counterOdd])
|
||||
while (cipherResult > 125) or (cipherResult < 32):
|
||||
if cipherResult > 125:
|
||||
cipherResult = 31 + (cipherResult - 125)
|
||||
if cipherResult < 32:
|
||||
cipherResult = 126 - (32 - cipherResult)
|
||||
messageDECIPHERAscii.append(cipherResult)
|
||||
|
||||
for char in messageDECIPHERAscii:
|
||||
messageDECIPHERchar.append(chr(char))
|
||||
|
||||
# Return a string
|
||||
messageDECIPHERAsciistr = ""
|
||||
for i in messageDECIPHERchar:
|
||||
messageDECIPHERAsciistr = messageDECIPHERAsciistr + i
|
||||
keyDECIPHERstr = ""
|
||||
for i in keyDECIPHERChar:
|
||||
keyDECIPHERstr = keyDECIPHERstr + i
|
||||
|
||||
return messageDECIPHERAsciistr, keyDECIPHERstr
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
message = "a simple message"
|
||||
key = "casualkeytouse"
|
||||
skey = "evenbetter"
|
||||
|
||||
print("==TESTING MODE==")
|
||||
print("=====")
|
||||
print("Testing '" + message + "' encoded with '" + key + "' secured by '" + skey + "'")
|
||||
print("=====")
|
||||
messaggio_cifrato, chiave_cifrata = cipher(message, key, skey)
|
||||
print(messaggio_cifrato)
|
||||
print(chiave_cifrata)
|
||||
print("=====")
|
||||
print("Decoding '" + message + "' encoded with '" + key + "' secured by '" + skey + "'")
|
||||
print("=====")
|
||||
messaggio_decifrato, chiave_decifrata = decipher(messaggio_cifrato, chiave_cifrata, "evenbetter")
|
||||
print(messaggio_decifrato)
|
||||
print(chiave_decifrata)
|
Loading…
x
Reference in New Issue
Block a user