Letter frequency substitution cipher
I'm having trouble getting my code to do this substitution cipher properly, my prompt is as follows: decrypt a cipher file assuming letter frequency correspondence between the cipher text and accepted English language frequency; i.e. if the most common letter in the cypher text is 'p' assume it is 'e' in plaintext; if the second most common letter in the cypher text is 'o' assume it is 't' in plaintext; etc.
alpha = [[0,'A'],[0,'B'],[0,'C'],[0,'D'],[0,'E'],[0,'F'],[0,'G'],[0,'H'],
[0,'I'],[0,'J'],[0,'K'],[0,'L'],[0,'M'],[0,'N'],[0,'O'],[0,'P'],
[0,'Q'],[0,'R'],[0,'S'],[0,'T'],[0,'U'],[0,'V'],[0,'W'],[0,'X'],
[0,'Y'],[0,'Z']]
fre = ["e","t","a","o","i","n","s","h",
"r","d","l","c","u","m","w","f",
"g","y","p","b","v","k","j","x",
"q","z"]
file = str(input(":"))
text = file.upper()
for c in text:
for e in alpha:
if c == e[0]:
e[0] += 1
for e in alpha:
e[0] = text.count(e[1])
alpha.sort()
alpha.reverse()
print(alpha)
text = text.replace(alpha[0][1],"e")
text = text.replace(alpha[1][1],"t")
text = text.replace(alpha[2][1],"a")
text = text.replace(alpha[3][1],"o")
text = text.replace(alpha[4][1],"i")
text = text.replace(alpha[5][1],"n")
text = text.replace(alpha[6][1],"s")
text = text.replace(alpha[7][1],"h")
text = text.replace(alpha[8][1],"r")
text = text.replace(alpha[9][1],"d")
text = text.replace(alpha[10][1],"l")
text = text.replace(alpha[11][1],"c")
text = text.replace(alpha[12][1],"u")
text = text.replace(alpha[13][1],"m")
text = text.replace(alpha[14][1],"w")
text = text.replace(alpha[15][1],"f")
text = text.replace(alpha[16][1],"g")
text = text.replace(alpha[17][1],"y")
text = text.replace(alpha[18][1],"p")
text = text.replace(alpha[19][1],"b")
text = text.replace(alpha[20][1],"v")
text = text.replace(alpha[21][1],"k")
text = text.replace(alpha[22][1],"j")
text = text.replace(alpha[23][1],"x")
text = text.replace(alpha[24][1],"q")
text = text.replace(alpha[25][1],"z")
print(text)
python
add a comment |
I'm having trouble getting my code to do this substitution cipher properly, my prompt is as follows: decrypt a cipher file assuming letter frequency correspondence between the cipher text and accepted English language frequency; i.e. if the most common letter in the cypher text is 'p' assume it is 'e' in plaintext; if the second most common letter in the cypher text is 'o' assume it is 't' in plaintext; etc.
alpha = [[0,'A'],[0,'B'],[0,'C'],[0,'D'],[0,'E'],[0,'F'],[0,'G'],[0,'H'],
[0,'I'],[0,'J'],[0,'K'],[0,'L'],[0,'M'],[0,'N'],[0,'O'],[0,'P'],
[0,'Q'],[0,'R'],[0,'S'],[0,'T'],[0,'U'],[0,'V'],[0,'W'],[0,'X'],
[0,'Y'],[0,'Z']]
fre = ["e","t","a","o","i","n","s","h",
"r","d","l","c","u","m","w","f",
"g","y","p","b","v","k","j","x",
"q","z"]
file = str(input(":"))
text = file.upper()
for c in text:
for e in alpha:
if c == e[0]:
e[0] += 1
for e in alpha:
e[0] = text.count(e[1])
alpha.sort()
alpha.reverse()
print(alpha)
text = text.replace(alpha[0][1],"e")
text = text.replace(alpha[1][1],"t")
text = text.replace(alpha[2][1],"a")
text = text.replace(alpha[3][1],"o")
text = text.replace(alpha[4][1],"i")
text = text.replace(alpha[5][1],"n")
text = text.replace(alpha[6][1],"s")
text = text.replace(alpha[7][1],"h")
text = text.replace(alpha[8][1],"r")
text = text.replace(alpha[9][1],"d")
text = text.replace(alpha[10][1],"l")
text = text.replace(alpha[11][1],"c")
text = text.replace(alpha[12][1],"u")
text = text.replace(alpha[13][1],"m")
text = text.replace(alpha[14][1],"w")
text = text.replace(alpha[15][1],"f")
text = text.replace(alpha[16][1],"g")
text = text.replace(alpha[17][1],"y")
text = text.replace(alpha[18][1],"p")
text = text.replace(alpha[19][1],"b")
text = text.replace(alpha[20][1],"v")
text = text.replace(alpha[21][1],"k")
text = text.replace(alpha[22][1],"j")
text = text.replace(alpha[23][1],"x")
text = text.replace(alpha[24][1],"q")
text = text.replace(alpha[25][1],"z")
print(text)
python
2
You forgot to add what the problem is you are encountering. "Having trouble" may be factually correct, but it does not help us helping you. Sample input and expected output may help us too.
– usr2564301
Nov 23 '18 at 23:30
1
See str.translate to do all the translations at once.
– Mark Tolonen
Nov 23 '18 at 23:44
add a comment |
I'm having trouble getting my code to do this substitution cipher properly, my prompt is as follows: decrypt a cipher file assuming letter frequency correspondence between the cipher text and accepted English language frequency; i.e. if the most common letter in the cypher text is 'p' assume it is 'e' in plaintext; if the second most common letter in the cypher text is 'o' assume it is 't' in plaintext; etc.
alpha = [[0,'A'],[0,'B'],[0,'C'],[0,'D'],[0,'E'],[0,'F'],[0,'G'],[0,'H'],
[0,'I'],[0,'J'],[0,'K'],[0,'L'],[0,'M'],[0,'N'],[0,'O'],[0,'P'],
[0,'Q'],[0,'R'],[0,'S'],[0,'T'],[0,'U'],[0,'V'],[0,'W'],[0,'X'],
[0,'Y'],[0,'Z']]
fre = ["e","t","a","o","i","n","s","h",
"r","d","l","c","u","m","w","f",
"g","y","p","b","v","k","j","x",
"q","z"]
file = str(input(":"))
text = file.upper()
for c in text:
for e in alpha:
if c == e[0]:
e[0] += 1
for e in alpha:
e[0] = text.count(e[1])
alpha.sort()
alpha.reverse()
print(alpha)
text = text.replace(alpha[0][1],"e")
text = text.replace(alpha[1][1],"t")
text = text.replace(alpha[2][1],"a")
text = text.replace(alpha[3][1],"o")
text = text.replace(alpha[4][1],"i")
text = text.replace(alpha[5][1],"n")
text = text.replace(alpha[6][1],"s")
text = text.replace(alpha[7][1],"h")
text = text.replace(alpha[8][1],"r")
text = text.replace(alpha[9][1],"d")
text = text.replace(alpha[10][1],"l")
text = text.replace(alpha[11][1],"c")
text = text.replace(alpha[12][1],"u")
text = text.replace(alpha[13][1],"m")
text = text.replace(alpha[14][1],"w")
text = text.replace(alpha[15][1],"f")
text = text.replace(alpha[16][1],"g")
text = text.replace(alpha[17][1],"y")
text = text.replace(alpha[18][1],"p")
text = text.replace(alpha[19][1],"b")
text = text.replace(alpha[20][1],"v")
text = text.replace(alpha[21][1],"k")
text = text.replace(alpha[22][1],"j")
text = text.replace(alpha[23][1],"x")
text = text.replace(alpha[24][1],"q")
text = text.replace(alpha[25][1],"z")
print(text)
python
I'm having trouble getting my code to do this substitution cipher properly, my prompt is as follows: decrypt a cipher file assuming letter frequency correspondence between the cipher text and accepted English language frequency; i.e. if the most common letter in the cypher text is 'p' assume it is 'e' in plaintext; if the second most common letter in the cypher text is 'o' assume it is 't' in plaintext; etc.
alpha = [[0,'A'],[0,'B'],[0,'C'],[0,'D'],[0,'E'],[0,'F'],[0,'G'],[0,'H'],
[0,'I'],[0,'J'],[0,'K'],[0,'L'],[0,'M'],[0,'N'],[0,'O'],[0,'P'],
[0,'Q'],[0,'R'],[0,'S'],[0,'T'],[0,'U'],[0,'V'],[0,'W'],[0,'X'],
[0,'Y'],[0,'Z']]
fre = ["e","t","a","o","i","n","s","h",
"r","d","l","c","u","m","w","f",
"g","y","p","b","v","k","j","x",
"q","z"]
file = str(input(":"))
text = file.upper()
for c in text:
for e in alpha:
if c == e[0]:
e[0] += 1
for e in alpha:
e[0] = text.count(e[1])
alpha.sort()
alpha.reverse()
print(alpha)
text = text.replace(alpha[0][1],"e")
text = text.replace(alpha[1][1],"t")
text = text.replace(alpha[2][1],"a")
text = text.replace(alpha[3][1],"o")
text = text.replace(alpha[4][1],"i")
text = text.replace(alpha[5][1],"n")
text = text.replace(alpha[6][1],"s")
text = text.replace(alpha[7][1],"h")
text = text.replace(alpha[8][1],"r")
text = text.replace(alpha[9][1],"d")
text = text.replace(alpha[10][1],"l")
text = text.replace(alpha[11][1],"c")
text = text.replace(alpha[12][1],"u")
text = text.replace(alpha[13][1],"m")
text = text.replace(alpha[14][1],"w")
text = text.replace(alpha[15][1],"f")
text = text.replace(alpha[16][1],"g")
text = text.replace(alpha[17][1],"y")
text = text.replace(alpha[18][1],"p")
text = text.replace(alpha[19][1],"b")
text = text.replace(alpha[20][1],"v")
text = text.replace(alpha[21][1],"k")
text = text.replace(alpha[22][1],"j")
text = text.replace(alpha[23][1],"x")
text = text.replace(alpha[24][1],"q")
text = text.replace(alpha[25][1],"z")
print(text)
python
python
edited Nov 24 '18 at 0:44
yoonghm
1,106918
1,106918
asked Nov 23 '18 at 23:17
Brice Brice
11
11
2
You forgot to add what the problem is you are encountering. "Having trouble" may be factually correct, but it does not help us helping you. Sample input and expected output may help us too.
– usr2564301
Nov 23 '18 at 23:30
1
See str.translate to do all the translations at once.
– Mark Tolonen
Nov 23 '18 at 23:44
add a comment |
2
You forgot to add what the problem is you are encountering. "Having trouble" may be factually correct, but it does not help us helping you. Sample input and expected output may help us too.
– usr2564301
Nov 23 '18 at 23:30
1
See str.translate to do all the translations at once.
– Mark Tolonen
Nov 23 '18 at 23:44
2
2
You forgot to add what the problem is you are encountering. "Having trouble" may be factually correct, but it does not help us helping you. Sample input and expected output may help us too.
– usr2564301
Nov 23 '18 at 23:30
You forgot to add what the problem is you are encountering. "Having trouble" may be factually correct, but it does not help us helping you. Sample input and expected output may help us too.
– usr2564301
Nov 23 '18 at 23:30
1
1
See str.translate to do all the translations at once.
– Mark Tolonen
Nov 23 '18 at 23:44
See str.translate to do all the translations at once.
– Mark Tolonen
Nov 23 '18 at 23:44
add a comment |
2 Answers
2
active
oldest
votes
Seems there's a potential for mix-up when you do the replace sequentially: suppose 'p' is the most common character in the cypher, and you replace it with 'e'. Later you're going to replace 'e' for something else, which will again scramble your result.
I would try something like (after you've got alpha sorted as you like):
''.join(map(dict(zip(fre, map(lambda a: a[1], alpha))).get, text))
Which creates a mapping from the cypher text to English text and applies it to the text directly.
1
He used uppercase to avoid this mix-up, which is fine as long as there is only lowercase text.
– myrmica
Nov 24 '18 at 20:37
@7t7Studios You're right >< In that case I can't spot anything inherently wrong with the logic...
– andersource
Nov 24 '18 at 21:18
add a comment |
You could also make the list alpha on the fly:
from string import ascii_letters
alpha =
fre = ["e","t","a","o","i","n","s","h",
"r","d","l","c","u","m","w","f",
"g","y","p","b","v","k","j","x",
"q","z"]
text = "rsy yrr" # cipher of "eat tee"
for letter in ascii_letters:
n = text.count(letter)
if n:
alpha.append([n, letter])
Then sort it in descending order:
alpha.sort(reverse=True)
Then extract letters and make a dictionary mapping ciphered letters to deciphered:
letters_by_freq = [pair[1] for pair in alpha]
deciph_dict = dict(zip(letters_by_freq, fre))
Finally replace all letters using a string translation table:
trans_table = str.maketrans(deciph_dict)
print(text.translate(trans_table))
Output: eat tee
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53453790%2fletter-frequency-substitution-cipher%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Seems there's a potential for mix-up when you do the replace sequentially: suppose 'p' is the most common character in the cypher, and you replace it with 'e'. Later you're going to replace 'e' for something else, which will again scramble your result.
I would try something like (after you've got alpha sorted as you like):
''.join(map(dict(zip(fre, map(lambda a: a[1], alpha))).get, text))
Which creates a mapping from the cypher text to English text and applies it to the text directly.
1
He used uppercase to avoid this mix-up, which is fine as long as there is only lowercase text.
– myrmica
Nov 24 '18 at 20:37
@7t7Studios You're right >< In that case I can't spot anything inherently wrong with the logic...
– andersource
Nov 24 '18 at 21:18
add a comment |
Seems there's a potential for mix-up when you do the replace sequentially: suppose 'p' is the most common character in the cypher, and you replace it with 'e'. Later you're going to replace 'e' for something else, which will again scramble your result.
I would try something like (after you've got alpha sorted as you like):
''.join(map(dict(zip(fre, map(lambda a: a[1], alpha))).get, text))
Which creates a mapping from the cypher text to English text and applies it to the text directly.
1
He used uppercase to avoid this mix-up, which is fine as long as there is only lowercase text.
– myrmica
Nov 24 '18 at 20:37
@7t7Studios You're right >< In that case I can't spot anything inherently wrong with the logic...
– andersource
Nov 24 '18 at 21:18
add a comment |
Seems there's a potential for mix-up when you do the replace sequentially: suppose 'p' is the most common character in the cypher, and you replace it with 'e'. Later you're going to replace 'e' for something else, which will again scramble your result.
I would try something like (after you've got alpha sorted as you like):
''.join(map(dict(zip(fre, map(lambda a: a[1], alpha))).get, text))
Which creates a mapping from the cypher text to English text and applies it to the text directly.
Seems there's a potential for mix-up when you do the replace sequentially: suppose 'p' is the most common character in the cypher, and you replace it with 'e'. Later you're going to replace 'e' for something else, which will again scramble your result.
I would try something like (after you've got alpha sorted as you like):
''.join(map(dict(zip(fre, map(lambda a: a[1], alpha))).get, text))
Which creates a mapping from the cypher text to English text and applies it to the text directly.
answered Nov 23 '18 at 23:41
andersourceandersource
51418
51418
1
He used uppercase to avoid this mix-up, which is fine as long as there is only lowercase text.
– myrmica
Nov 24 '18 at 20:37
@7t7Studios You're right >< In that case I can't spot anything inherently wrong with the logic...
– andersource
Nov 24 '18 at 21:18
add a comment |
1
He used uppercase to avoid this mix-up, which is fine as long as there is only lowercase text.
– myrmica
Nov 24 '18 at 20:37
@7t7Studios You're right >< In that case I can't spot anything inherently wrong with the logic...
– andersource
Nov 24 '18 at 21:18
1
1
He used uppercase to avoid this mix-up, which is fine as long as there is only lowercase text.
– myrmica
Nov 24 '18 at 20:37
He used uppercase to avoid this mix-up, which is fine as long as there is only lowercase text.
– myrmica
Nov 24 '18 at 20:37
@7t7Studios You're right >< In that case I can't spot anything inherently wrong with the logic...
– andersource
Nov 24 '18 at 21:18
@7t7Studios You're right >< In that case I can't spot anything inherently wrong with the logic...
– andersource
Nov 24 '18 at 21:18
add a comment |
You could also make the list alpha on the fly:
from string import ascii_letters
alpha =
fre = ["e","t","a","o","i","n","s","h",
"r","d","l","c","u","m","w","f",
"g","y","p","b","v","k","j","x",
"q","z"]
text = "rsy yrr" # cipher of "eat tee"
for letter in ascii_letters:
n = text.count(letter)
if n:
alpha.append([n, letter])
Then sort it in descending order:
alpha.sort(reverse=True)
Then extract letters and make a dictionary mapping ciphered letters to deciphered:
letters_by_freq = [pair[1] for pair in alpha]
deciph_dict = dict(zip(letters_by_freq, fre))
Finally replace all letters using a string translation table:
trans_table = str.maketrans(deciph_dict)
print(text.translate(trans_table))
Output: eat tee
add a comment |
You could also make the list alpha on the fly:
from string import ascii_letters
alpha =
fre = ["e","t","a","o","i","n","s","h",
"r","d","l","c","u","m","w","f",
"g","y","p","b","v","k","j","x",
"q","z"]
text = "rsy yrr" # cipher of "eat tee"
for letter in ascii_letters:
n = text.count(letter)
if n:
alpha.append([n, letter])
Then sort it in descending order:
alpha.sort(reverse=True)
Then extract letters and make a dictionary mapping ciphered letters to deciphered:
letters_by_freq = [pair[1] for pair in alpha]
deciph_dict = dict(zip(letters_by_freq, fre))
Finally replace all letters using a string translation table:
trans_table = str.maketrans(deciph_dict)
print(text.translate(trans_table))
Output: eat tee
add a comment |
You could also make the list alpha on the fly:
from string import ascii_letters
alpha =
fre = ["e","t","a","o","i","n","s","h",
"r","d","l","c","u","m","w","f",
"g","y","p","b","v","k","j","x",
"q","z"]
text = "rsy yrr" # cipher of "eat tee"
for letter in ascii_letters:
n = text.count(letter)
if n:
alpha.append([n, letter])
Then sort it in descending order:
alpha.sort(reverse=True)
Then extract letters and make a dictionary mapping ciphered letters to deciphered:
letters_by_freq = [pair[1] for pair in alpha]
deciph_dict = dict(zip(letters_by_freq, fre))
Finally replace all letters using a string translation table:
trans_table = str.maketrans(deciph_dict)
print(text.translate(trans_table))
Output: eat tee
You could also make the list alpha on the fly:
from string import ascii_letters
alpha =
fre = ["e","t","a","o","i","n","s","h",
"r","d","l","c","u","m","w","f",
"g","y","p","b","v","k","j","x",
"q","z"]
text = "rsy yrr" # cipher of "eat tee"
for letter in ascii_letters:
n = text.count(letter)
if n:
alpha.append([n, letter])
Then sort it in descending order:
alpha.sort(reverse=True)
Then extract letters and make a dictionary mapping ciphered letters to deciphered:
letters_by_freq = [pair[1] for pair in alpha]
deciph_dict = dict(zip(letters_by_freq, fre))
Finally replace all letters using a string translation table:
trans_table = str.maketrans(deciph_dict)
print(text.translate(trans_table))
Output: eat tee
answered Nov 24 '18 at 20:31
myrmicamyrmica
46918
46918
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53453790%2fletter-frequency-substitution-cipher%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
You forgot to add what the problem is you are encountering. "Having trouble" may be factually correct, but it does not help us helping you. Sample input and expected output may help us too.
– usr2564301
Nov 23 '18 at 23:30
1
See str.translate to do all the translations at once.
– Mark Tolonen
Nov 23 '18 at 23:44