Caesar's cypher working incorrectly
2 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Hello,
I'm writing a Matlab code that reads text from a .txt file and encodes it using Caesar's cypher. The shift value is inputted from the keyboard.
As long as I only use uppercase letters, the code works pefectly. The probles is that lowercase letters are encoded wrongly. I understand that Matlab converts it to ASCII values and applies the shift on that value, then reconverts it, but i can't seem to identify the problem. I've used the same formula for Python also and there it works fine.
This is my code:
clc; close all; clear;
% Read input text file
input_file = 'input.txt';
fid = fopen(input_file, 'r');
input_text = fscanf(fid, '%c');
fclose(fid);
% Get shift from user input
shift = input('Enter shift value: ');
% Apply Caesar cipher to each character in input text
output_text = '';
for i = 1:length(input_text)
% Shift uppercase letters
if isletter(input_text(i)) && upper(input_text(i))
output_text = [output_text, char(mod(double(input_text(i)) - 65 + shift, 26) + 65)];
% Shift lowercase letters
elseif isletter(input_text(i)) && islower(input_text(i))
output_text = [output_text, char(mod(double(input_text(i)) - 97 + shift, 26) + 97)];
% Leave non-letter characters unchanged
else
output_text = [output_text, input_text(i)];
end
end
% Write output text file
output_file = 'output1.txt';
fid = fopen(output_file, 'w');
fprintf(fid, '%s', output_text);
fclose(fid);
And these are the input and outputs that i get, using a shift of 1:

I'm open to any suggestions.
Thank you.
0 commentaires
Réponses (2)
Voss
le 18 Mar 2023
Modifié(e) : Voss
le 18 Mar 2023
I can't find the function islower in MATLAB. Maybe that's a function you wrote yourself, and if so maybe it works correctly, but it's never going to be called in this code. The reason is that the if condition
if isletter(input_text(i)) && upper(input_text(i))
% ^^^^^^^^^^^^^^^^^^^^ this is a character
is always true when isletter(input_text(i)) is true, because upper(input_text(i)) returns a character whose ASCII value is something other than 0 when input_text(i) is a letter, so upper(input_text(i)) evaluates to true, so the entire if condition is true when isletter(input_text(i)) is true.
Therefore the elseif condition
elseif isletter(input_text(i)) && islower(input_text(i))
% ^^^^^^^^^^^^^^^^^^^^^^ this is never evaluated
is only checked when isletter(input_text(i)) is false, and in that case the first part of the elseif condition is false, so the second part is never checked because && short-circuits.
Maybe you have a function called isupper that works that you can use in place of upper, or maybe you had isupper there originally and you got an error because that function doesn't exist, so you changed it to upper, which created this situation where the corresponding error trying to use islower will never be seen because islower is never called for the reason explained above. I don't know, but in any case, one way to solve this without using the unknown functions isupper/islower is to use isstrprop, as shown below.
% Read input text file
input_file = 'input.txt';
fid = fopen(input_file, 'r');
input_text = fscanf(fid, '%c');
fclose(fid);
% Get shift from user input
% shift = input('Enter shift value: ');
shift = 1;
% Apply Caesar cipher to each character in input text
output_text = '';
for i = 1:length(input_text)
% Shift uppercase letters
if isstrprop(input_text(i),'upper')
output_text = [output_text, char(mod(double(input_text(i)) - 65 + shift, 26) + 65)];
% Shift lowercase letters
elseif isstrprop(input_text(i),'lower')
output_text = [output_text, char(mod(double(input_text(i)) - 97 + shift, 26) + 97)];
% Leave non-letter characters unchanged
else
output_text = [output_text, input_text(i)];
end
end
% Write output text file
output_file = 'output1.txt';
fid = fopen(output_file, 'w');
fprintf(fid, '%s', output_text);
fclose(fid);
type output1.txt % show the output file's contents
Note that you can process your entire file at once instead of one character at a time:
% Read input text file
input_file = 'input.txt';
fid = fopen(input_file, 'r');
input_text = fscanf(fid, '%c');
fclose(fid);
% Get shift from user input
% shift = input('Enter shift value: ');
shift = 1;
% Apply Caesar cipher to each character in input text
output_text = input_text;
isU = isstrprop(input_text,'upper');
isL = isstrprop(input_text,'lower');
output_text(isU) = char(mod(double(input_text(isU)) - 65 + shift, 26) + 65);
output_text(isL) = char(mod(double(input_text(isL)) - 97 + shift, 26) + 97);
% Write output text file
output_file = 'output1.txt';
fid = fopen(output_file, 'w');
fprintf(fid, '%s', output_text);
fclose(fid);
type output1.txt % show the output file's contents
2 commentaires
Voss
le 18 Mar 2023
You're welcome!
Note that your updated code still suffers from the same problems as the original. Specifically, lower will never be called for the reason described in my answer, and you should use isstrprop to test for upper- or lower-case.
John D'Errico
le 18 Mar 2023
Modifié(e) : John D'Errico
le 18 Mar 2023
Question: What do the functions upper, and islower do in MATLAB?
help upper
So upper converts a string to entirely uppercase. It is NOT a test.
upper('The quick brown Fox')
As well, there is no islower function in MATLAB, but it does seem to exist in python.
which islower
0 commentaires
Voir également
Catégories
En savoir plus sur Language Support dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!