Disclaimer: this is actually a coding challenge therefore I am expressly not looking for complete solutions.
The way the cipher works is as follows:
Start with ABCDEFGHIJKLMNOPQRSTUVWXYZ and a keyword KEYWORD. We construct our first alphabet by shuffling the above around each letter of the keyword in turn. I.e.:
First letter K, alphabet becomes LMNOPQRSTUVWXYZKABCDEFGHIJ
Second letter E, alphabet becomes FGHIJELMNOPQRSTUVWXYZKABCD
etc. etc. until we get the initial cipher alphabet: YFGHIJELMNRPQDSTUVOXWZKABC
In order to encrypt we then use this alphabet and for each letter in the plain text perform the same shuffling operation as in the inception stage around the plaintext letter (so if the first letter of the plaintext is F you would get J as the first ciphertext letter and your new alphabet would be GHIJELMNRPQDSTUVOXWZKABCFY
How would I go about solving this? I'm thinking known plaintext attack since I most likely know the beginning of the plaintext and also know that there are only a finite amount of possible words in the solution.
Further research led me to an obscure cipher Chaoscipher which goes in that direction.
Edit: longer example (also uses keyword as keyword):
doyouthinkthereisanotherwaytosolvethiscipher
becomes
HFUTLNAQYWHBWBEBTIEXWSZFGZQPINTQGHKDSVVVPXNM
Second edit: python code to test it
class ScrabbleCipher:
def __init__(self, keyword):
self.alpha = string.ascii_uppercase
self.keyword = keyword.upper()
self.initialAlpha()
def initialAlpha(self):
for i in self.keyword:
self.shuffle(i)
self.initial = self.alpha
def shuffle(self, letter):
try:
tg = self.alpha.index(letter)
except Exception as e:
print letter
self.alpha = self.alpha[tg+1:] + letter + self.alpha[:tg]
def encrypt(self, plaintext):
self.alpha = self.initial
plaintext = plaintext.upper()
ciphertext = ''
for i in plaintext:
pos = string.ascii_uppercase.index(i)
ciphertext += self.alpha[pos]
self.shuffle(i)
return ciphertext
def decrypt(self, ciphertext):
ciphertext = self.sani(ciphertext)
self.alpha = self.initial
plaintext = ''
for i in ciphertext:
pos = self.alpha.index(i)
corLet = string.ascii_uppercase[pos]
plaintext += corLet
self.shuffle(corLet)
return plaintext