Effacer les filtres
Effacer les filtres

Caesar's cypher working incorrectly

6 vues (au cours des 30 derniers jours)
Carmen Chira
Carmen Chira le 18 Mar 2023
Commenté : Voss le 18 Mar 2023
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.

Réponses (2)

Voss
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
B C D E F G H BOB BSF NFSF bob bsf nfsf Bob bsf nfsf
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
B C D E F G H BOB BSF NFSF bob bsf nfsf Bob bsf nfsf
  2 commentaires
Carmen Chira
Carmen Chira le 18 Mar 2023
Hi!
yes, i forgot edit this post after i saw some errors in my code. Now it looks like this:
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)) && lower(input_text(i)))
output_text(i) = [output_text, char(mod((double(input_text(i))+ shift - 97),26) + 97)];
% Leave non-letter characters unchanged
else
output_text = [output_text, input_text(i)];
end
end
% Write output text file
output_file = 'output2.txt';
fid = fopen(output_file, 'w');
fprintf(fid, '%s', output_text);
fclose(fid);
But thank you so much for your help! This definetly simplifies everything.
Voss
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.

Connectez-vous pour commenter.


John D'Errico
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
UPPER Convert to uppercase NEWSTR = UPPER(STR) converts any lowercase characters in STR to the corresponding uppercase character and leaves all other characters unchanged. STR can be a string, character vector, or a cell array of character vectors. NEWSTR is the same type and shape as STR. Example: STR = 'DATA.tar.gz'; upper(STR) returns DATA.TAR.GZ Example: STR = ["FUNDS.xlsx";"PAPER.docx"]; upper(STR) returns "FUNDS.XLSX" "PAPER.DOCX" See also LOWER, STRING, ISSTRPROP, REVERSE Documentation for upper doc upper Other uses of upper codistributed/upper tokenizedDocument/upper
So upper converts a string to entirely uppercase. It is NOT a test.
upper('The quick brown Fox')
ans = 'THE QUICK BROWN FOX'
As well, there is no islower function in MATLAB, but it does seem to exist in python.
which islower
'islower' not found.

Catégories

En savoir plus sur Characters and Strings dans Help Center et File Exchange

Produits


Version

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by