1,046 views (last 30 days)

Show older comments

Caesar's cypher is the simplest encryption algorithm. It adds a fixed value to the ASCII (unicode) value of each character of a text. In other words, it shifts the characters. Decrypting a text is simply shifting it back by the same amount, that is, it substract the same value from the characters. Write a function called caesar that accepts two arguments: the first is the character vector to be encrypted, while the second is the shift amount. The function returns the output argument coded, the encrypted text. The function needs to work with all the visible ASCII characters from space to ~. The ASCII codes of these are 32 through 126. If the shifted code goes outside of this range, it should wrap around. For example, if we shift ~ by 1, the result should be space. If we shift space by -1, the result should be ~.

for the first part of the code...this works

function coded=caesar(A,n)

char_set=char(32):char(126)

coded=char(A+n);

end

But if i want to maintain the range between 32 and 126 ....and also wrap around the same values as asked in later half of question , it doesnt work

function coded=caesar(A,n)

char_set=char(32):char(126)

while A <=char_set

coded=char(A+n);

end

end

please help me with the concerned code buiding ....( expect a simple approach , since iam a begineer)

test for these outputs

caesar('ABCD',1)

ans =

'BCDE'

caesar('xyz ~',1)

ans =

'yz{! '

caesar('xyz ~',-1)

ans =

'wxy~}' %these are correct answers to the code

Rik
on 28 Sep 2020

@Danial, which code are you talking about? Sonu already mentioned their code doesn't work.

Yitong Liu
on 24 Aug 2019

Edited: per isakson
on 2 May 2020

function coded = caesar(M, n)

num = double(M); %Converts string into double

num2 = num;

N = n - 95 * fix(n/95);

for i = 1:length(num);

if num(i) + N < 32 %If ASCII value goes below 32

num2(i) = 126 - (31- num(i) - N);

elseif num(i) + N > 126 %If ASCII value goes beyond 126

num2(i) = 32 + (num(i) + N -127);

else

num2(i) = num(i) + N ; %If ASCII value goes normal

end

coded = char(num2);

end

I spent halfhour on solving this problem, a little bit hard.

This is correct code. Hope it helps.

Walter Roberson
on 1 Mar 2021

That has already been explained several times, starting at https://www.mathworks.com/matlabcentral/answers/466636-caesar-cyphor-encryption-problem#comment_832722

You may need to "Show 22 older comments" to read the discussion.

Marilou
on 17 Oct 2019

function coded= caesar(string,shift)

value=string+shift;

for i=1:length(value)

while value(i)<32

value(i)=value(i)+95;

end

while value(i)>126

value(i)=value(i)-95;

end

end

coded=char(value);

Walter Roberson
on 16 Feb 2021

Suppose the input were

char(126)

and you were asked to shift it forward by 2 positions. What is the expected output? We read the problem requirements:

function needs to work with all the visible ASCII characters from space to ~. The ASCII codes of these are 32 through 126. If the shifted code goes outside of this range, it should wrap around

Wrap around in that forward direction means that the character after char(126) should be char(32) then char(33), then char(34) and so on. Thus if we started with ~ (char 126) and shifted forward two, we need to end up with char(33)

char(34)

which is

original = 126

shift = 2

target = 33

amount_to_go_back = original + shift - target

which also happens to be

length(32:126)

Pavel Radko
on 11 Aug 2020

Edited: Pavel Radko
on 13 Aug 2020

Thanks to a person who told about circshift function. I've been tried several hours to solve this task without that function.

So finaly I've passed all tests. And final code is much shorter and elegant as I have at today's morning ))

It has only 4 lines including the "end".

The main idea is to shift character table, but not the symbols of input.

% Write a function "caesar" that uses as input "array" - array

% of ASCII table characters, and "shift" - the value (integer) of shifting the "array" elements

% via ASCII table (from 32nd to 126th)

function coded = caesar (array,shift)

shifted_array=circshift(char(32:126),-shift);

% we shift (roll) ASCII characters from 32 to 126 on the "shift" amount

% note that we use "-shift", because we shift the character table but not

% the characters in our "array"

% as output we get all ASCII characters from 32 to 126 but shifted (rolled)

coded = shifted_array(double(array)-31)

% double(array) - gets array of numbers that correspond to ASCII character

% table

% (double(array)-31) - this outs array of numbers with caracter indices

% shifted by -31

% "-31" because we use "shifted_array" that hasnt ASCII characters from 1 to 31

% shifted_array() - uses array of numbers in parentheses as shifted table

% indices and outputs corresponding characters from it

end

Wilver Sánchez
on 7 Feb 2020

function coded = caesar(text,amound)

n=amound - 95 * fix(amound/95);

v=double(text)+n;

v(v<32)=126-(31-v(v<32));

v(v>126)=32+(-127+v(v>126));

coded=char(v);

end

Wilver Sánchez
on 7 Feb 2020

Guillaume
on 12 Jun 2019

>> mod(0:51, 26)

ans =

Columns 1 through 21

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

Columns 22 through 42

21 22 23 24 25 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

Columns 43 through 52

16 17 18 19 20 21 22 23 24 25

You can see that values 26, 27, ... go back to 0, 1, ...

Add/subtract some offsets to do the same for values in the range 32:126

Walter Roberson
on 9 Jan 2021

mod() works for negative shifts too

S = 'xyla'

shift = 5

char('a' + mod(S - 'a' + shift,26))

char('a' + mod(S - 'a' - shift,26))

Zeyuan Cao
on 7 Feb 2020

I came up with an approach which uses logical indexing instead of if statement

function coded=caesar(str,n)

str1=double(str);

m=n-95*floor(n/95);

codedstr1=str1+m;

codedstr1(codedstr1>=127)=codedstr1(codedstr1>=127)-127+32;

coded=char(codedstr1);

end

Sahil
on 19 Mar 2020

Dude this only half the solution you missed " message + n < 32 " condition

function coded = caesar(message , n)

msg = double(message);

m = mod(n, 95);

coded_msg = msg + m;

coded_msg(coded_msg > 126) = coded_msg(coded_msg > 126) - 127 + 32;

coded_msg(coded_msg < 32) = coded_msg(coded_msg < 32) + 127 -32;

coded =char(coded_msg);

end

Cyrus David Pastelero
on 8 Jul 2020

Edited: Cyrus David Pastelero
on 8 Jul 2020

%This is my aproach to the problem.

function coded = caesar(arr, num)

size = strlength(arr);

coded = arr+num

for i = 1:size

while coded(i)> 126

coded(i) = coded(i) - 95;

end

while coded(i) < 32

coded(i) = coded(i) + 95;

end

end

coded = char(coded);

end

CCF2017 MIT
on 2 Jul 2019

Edited: CCF2017 MIT
on 2 Jul 2019

This problem is asking you to shift the character variable by a given element n

the word wrap means that if the ASCII code of your character exceeds 32 or 126 you need to circle back again .

For example

if ASCII code is 97 and n (shift variable) is 45 so your ASCII code is 142 which exceeds 126. So you need to subtract 126 from 142

142-126, and add the net result to 31.

you need'nt do all that..... use the function called circshift

so i defined a character array from 32 to 126 which is the required ascii range

ch=char(32:126)

these are the characters.

ch =

' !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~'

and when i use the circshift command

ch_shift_pos=circshift(ch,2)

ch_shift_pos =

'}~ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|'

ch_shift_neg=circshift(ch,-2)

ch_shift_neg=

'"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ !'

Notice how the characters have shifted by 2 positions without you having to manually keep it within its range.

now if i want to find a character and its corresponding encrypted/shifted value i simply transfer the index since both ch and ch_shift are of the same size

so for example: if i want to find the encryption character of a , i first find the index of a in the 'ch' array and store it in a variable called x

x=strfind(ch,'a')

x =

66

and then i use that index to find the encryption in the shifted array

ch_shift_pos(x)

ans =

'_'

ch_shift_neg(x)

ans =

'c'

There! thats your answer. As simple as that. But i had to rack my brains for it. :P

Guillaume
on 2 Jul 2019

I have explained how to do it in various comments here. I'm not sure how I can explain it more without giving the solution away.

In one comment, I wrote that all that is needed is: "a subtraction by an integer, a mod, an addition by the same integer" (and a conversion to char afterwards).

You have a message with a set of numbers (characters) between two values a and b. Shift that set of numbers so that it is between 0 and b-a. Add your caesar shift. This may underflow 0 or overflow b-a. Apply mod so that it wraps back between 0 and b-a. Reverse your original shift so that the numbers are once agian between a and b.

Rahul Gulia
on 22 Jul 2019

Edited: Guillaume
on 22 Jul 2019

function coded = caesar(str,n)

num1 = double(str); %Converting string to double to make the defined shifts

for i = 1 : length(num1)

if num1(i) + n > 126 % If ASCII value goes beyond 126

m = num1(i)-126+n;

p = 31+m;

num1(i) = p;

elseif num1(i)+n < 32 % If ASCII value goes below 32

m = 32 - num1(i) + n;

p = 126 - m;

num1(i) = p;

else m = num1(i) + n; % In a normal condition

num1(i) = m;

end

code(i) = num1(i);

end

coded = char(code);

I have written this code. Can anyone please expain as what is wrong in here? I know i have made a mistake. But i am not able to figure it out.

Thanks in advance.

Walter Roberson
on 12 Jul 2020

Suppose n = 1000 and the character vector is 'a' (which is 97 decimal). num1 would become 97. num1(1)+1000 > 126, so m = 97-126+1000 would be m=971. Then p=31+971 gives p = 1002 . This is not the desired result.

The code needs to adjust num1+n to be between 32 and 126 (inclusive)

Sahil
on 19 Mar 2020

function coded = caesar(message , n)

msg = double(message);

m = mod(n, 95); % this contricts the key within the range

coded_msg = msg + m;

coded_msg(coded_msg > 126) = coded_msg(coded_msg > 126) - 95;

coded_msg(coded_msg < 32) = coded_msg(coded_msg < 32) + 95;

coded =char(coded_msg);

end

Capulus_love
on 12 Aug 2020

thanks. i miss the sentence

m = mod(n, 95); % this contricts the key within the range

now i pass this question! :)

shreyansh pitroda
on 30 Mar 2020

%% Function encode the code by shifting it by amount user as specified

function [coded]= caesar(code , shift) %% TAKES TWO VALUE CODE AND AMOUNT OF SHIFT

A = double(code);

x = 1;

z = length(A);

z = z+ 1;

shift = shift - 95*(fix(shift/95));

code(1:end) = code(1:end) + shift;

while x ~= z %%used the while loop to provide count

if code(1,x)< 32 %%if the value is below 32

A(1,x) = A(1,x) - 32;

A(1,x) = A(1,x) + shift;

A(1,x) = A(1,x) + 127;

elseif (code(1,x)>32)&&(code(1,x)<127) %% if value is between 32 and 127

A(1,x) = A(1,x) + shift;

else %% if the value is greater than 127

A(1,x) = A(1,x) - 127;

A(1,x) = A(1,x) + shift;

A(1,x) = A(1,x) + 32;

end

x= x + 1;

end

coded = char(A); %% code print

end

Washida Kami
on 31 Mar 2020

%uses the mod function

function txt = caesar(txt,key)

txt = double(txt) + key;

first = double(' ');

last = double('~');

% use mod to shift the characters - notice the + 1

% this is a common error and results in shifts

% being off by 1

txt = char(mod(txt - first,last - first + 1) + first);

end

%uses the circshift function

function y = caesar2(ch, key)

v = ' ' : '~';

[~, loc] = ismember(ch, v);

v2 = circshift(v, -key);

y = v2(loc);

end

Walter Roberson
on 20 Aug 2020

Rajat Munjal
on 13 Apr 2020

function coded = caesar(ctbe,sa)

dd = double(ctbe)

if dd>=32 & dd<=126

ss =dd +sa

ss(ss<32) = rem((ss(ss<32)-32),95)+127

ss(ss>126)=rem((ss(ss>126)-126),95)+31

coded =char(ss);

end

end

Walter Roberson
on 13 Apr 2020

dd = double(ctbe)

ctbe will be a vector of char, so dd will be a vector of double.

if dd>=32 & dd<=126

dd>=32 & dd<=126 would be a logical vector. When you test a non-scalar with if or while, it is considered true if all of the items being tested are non-zero (true). If even one of the entries was not within that range then the test would be considered false as a whole... and you have no else condition so nothing would be assigned to coded

Olel Arem
on 30 Apr 2020

Edited: Olel Arem
on 30 Apr 2020

Short code with use of Logical Indexing:

function coded= caesar(string,shift)

mod_str=string+shift;

for i=1:length(mod_str)

mod_str(mod_str<32)=mod_str(mod_str<32)+95;

mod_str(mod_str>126)=mod_str(mod_str>126)-95;

end

coded=char(mod_str);

Omkar Kadam
on 9 May 2020

function coded = caesar(V,N)

ascii = char(32:126);

coded1 = (double(V) + N - 31);

found = false;

ii = 1;

coded2 = [];

while ~(found)

if ii < length(coded1)+1

j = coded1(ii);

ii = ii +1;

while j < 32

j = j + 126 - 31;

end

while j > length(ascii)

j = j - length(ascii);

end

coded2 = abs([coded2,j]);

else

found = true;

break;

end

end

coded = ascii(coded2); %this is 100% working code.

GAURAV RAJ
on 10 May 2020

help me in this . i wrote this code but i am getting error please tell me what's wrong in this

function y=caesar(a,b)

q=double(a);

for i=1:length(a)

d(i)=q(i)+b;

if d(i)>=32;

e(i)=rem(d(i),126);

else

e(i)=95+d(i);

end

if e(i)>=32 ;

y(i)=char(e(i));

elseif e(i)==0;

y(i)=char(126);

else

e(i)=e(i)+31;

y(i)=char(e(i));

end

end

end

Walter Roberson
on 11 May 2020

Suppose b is -200 and q is double('A') = 65.

d = 65-200 -> d = -135

-135 >= 32 is false, so

e = 95 + -135 = -40

-40 >= 32 is false

-40 == 0 is false

e(i) = -40 + 31 = -9

y(i) = char(-9) which is same as char(0)

Arafat Roney
on 11 May 2020

function coded=caesar(c,s)

n=mod(s,95);

sc=c+n;

l=length(sc);

w=[];

for i=1:l

if sc(i)>126

p=31+(sc(i)-126);

elseif sc(i)<32

p=126-abs(sc(i)-31);

else

p=sc(i);

end

w=[w p];

end

coded=char(w);

end

Shandilya Kiran Bhatt
on 12 May 2020

Edited: Walter Roberson
on 12 May 2020

The code below is a long one but it is using a while loop and if you read it, it is an easy one and it is correct for any random shifts.

function coded = caesar(A,n)

a = double(A);

z = a + n;

for i =1: length(a)

if z(i)>126

b = z(i) - 126;

if b <=95

z(i) = 31 + b;

else

while b > 95

b = b-95;

end

z(i) = 31 + b;

end

end

if z(i) < 32

c = 32 - z(i);

if c <= 95

z(i) = 127 - c;

else

while c >95

c = c - 95;

end

z(i) = 127 -c;

end

end

end

encrypted_code = z;

coded = char(encrypted_code);

end

SAMARTH MAHESHKUMAR GEMLAWALA
on 15 May 2020

This code is quite lenghty, but logic that i have used is quite simple understand

function coded = caesar(A, n)

a = double(A)

ele=size(a)

for i=1:ele(1,2)

if n>=0

for j=1:n

a(i) = a(i)+1;

if a(i)>126

a(i)=32;

end

end

end

if n<0

for j=1:abs(n)

a(i) = a(i)-1;

if a(i)<32

a(i)=126;

end

end

end

end

coded = char(a);

end

Julian Veran
on 18 May 2020

function coded = caesar(M, n)

num = double(M); %Converts string into double

num2 = num;

N = n - 95 * fix(n/95);

for i = 1:length(num);

if num(i) + N < 32 %If ASCII value goes below 32

num2(i) = 126 - (31- num(i) - N);

elseif num(i) + N > 126 %If ASCII value goes beyond 126

num2(i) = 32 + (num(i) + N -127);

else

num2(i) = num(i) + N ; %If ASCII value goes normal

end

coded = char(num2);

end

Tatiana Suaza Varela
on 19 Dec 2020

Julian Veran
on 18 May 2020

(using mod function)

function txt = caesar(txt,key)

txt = double(txt) + key;

first = double(' ');

last = double('~');

% use mod to shift the characters - notice the + 1

% this is a common error and results in shifts

% being off by 1

txt = char(mod(txt - first,last - first + 1) + first);

end

(using circ shify function)

function y = caesar2(ch, key)

v = ' ' : '~';

[~, loc] = ismember(ch, v);

v2 = circshift(v, -key);

y = v2(loc);

end

Timothy Simon Thomas
on 19 May 2020

%% CAESAR's SIPHER

% CAESAR(message,code): Message is the message to be encripted

% CODE represents the ASCII shift

% Wrapping always enabled

function coded = caesar(message,code)

while(code>95)

code=code-95;

end

while(code<-95)

code=code+95;

end

message=message+code; %base case

message(message>126)=char(double(message(message>126))-95) %overshoot

message(message<32)=char(double(message(message<32))+95) %undershoot

coded=char(message);

end

Taif Ahmed BIpul
on 21 May 2020

function coded=caesar(v,n)

x=double(v)+n;

q=x(x<32);

p=x(x>126);

while q<32;

x(x<32)=x(x<32)+95;

q=x(x<32);

end

while p>126;

x(x>126)=x(x>126)-95;

p=x(x>126);

end

coded=char(x);

end

yazan ziyad
on 29 May 2020

here you go

function [coded]=caesar(a,shift)

m=double(a)

codedd=m+shift;

for i=1:abs(shift)

codedd(codedd<32)=127-(32-codedd(codedd<32));

codedd(codedd>126)=31+(codedd(codedd>126)-126)

coded=char(codedd)

end

end

SONU NIGAM
on 29 May 2020

function coded = caesar(char_vec,shift_amount)

char_value = char_vec+shift_amount;

for ii = 1:length(char_value)

if char_value>126

coded = char(char_value-95);

elseif char_value<32

coded = char(char_value+95);

else

coded = char(char_value);

end

end

end

I got correct output but in the assignment when i run this program it shows error...What fault i did i m unable to notice,if anyone can explain me then plz help me.

Soroush sa
on 30 May 2020

I'm beginner and I have written this code. Can anybody help me by expaining that what is wrong in here?

function coded = caesar(string,shift)

double_A = double(string);

position = double_A + shift;

for ii = 1:length(position)

if position > 126

new_position = position - 95;

elseif position < 32

new_position = position + 95;

else

new_position = position;

end

end

coded = char(new_position);

end

Sumit Kumar Sharma
on 4 Jun 2020

function coded=caesar(a,b)

x=double(a);

k=mod(b,95);

q=[];

for j=1:length(x)

p=x(j)+k;

if p<=126 && p>=32

q=[q p];

elseif p>126

r=p-95;

q=[q r] ;

elseif p<32

s=p+95;

q=[q s];

end

end

coded=char(q);

end

Vistasp Edulji
on 22 Jun 2020

A much shorter solution is possible using logical arrays.

function coded =caesar(str, n)

coded = str + n;

while ( sum(coded >= 127) > 0 || sum(coded <= 31) >0 )

coded(coded >= 127) = 31 + (coded(coded>=127)-126);

coded(coded <= 31) = 127 - (32-coded(coded<=31));

end

coded = char(coded);

The while loop condition simply ensures that there is no overflow after each round of correction

The important thing is your output should be a string

Alankriti Mallick
on 26 Jul 2020

function coded= caesar(v,s)

v=v+s;

v(v>126)=rem(v(v>126),95);

v(v<32)=127-rem(32-v(v<32),95);

coded=char(v);

Ankit singh chauhan
on 16 Aug 2020

Edited: Walter Roberson
on 16 Aug 2020

function cloud=caesar(m,n)

sum=double(m+n);

for i=1:length(sum)

if n>0

if (sum(i)<127)

cloud(i)=char(sum(i));

elseif sum(i)>126

store=sum(i)-126;

sto=mod(store,95);

if sto==0

s=126;

cloud(i)=char(s+sto);

else

s=32;

cloud(i)=char(s+sto-1);

end

end

else

if n<0

if (sum(i)>=32)

cloud(i)=char(sum(i));

else

if sum(i)<32

store=32-sum(i);

sto=mod(store,95);

cloud(i)=char(126-sto+1);

end

end

end

end

end

end

Juan Sebastián Hincapié Montes
on 21 Aug 2020

Edited: Juan Sebastián Hincapié Montes
on 21 Aug 2020

function [coded] = caesar(v ,sa)

secret = double(v);

code = ones(1, length(v));

for ii=1:length(secret)

if secret(ii)+sa > 126 %greater than 126

remainder=rem(sa,95);

if remainder + secret(ii)>126 %if the double plus the remainder is greater than 32

code(ii)=31+(remainder-(126-secret(ii)));

else

code(ii)=remainder+secret(ii); %if the double plus the remainder isn't greater than 32

end

elseif secret(ii)+sa < 32 %lower than 32

remainder=abs(rem(sa,95));

if secret(ii)-remainder < 32 %if the double plus the remainder is lower than 32

code(ii)=127-(remainder-(secret(ii)-32));

else

code(ii)=secret(ii)-remainder; %if the double plus the remainder isn't lower than 32

end

else

code(ii) = sa + secret(ii); %everything is normal

end

end

coded=char(code);

end

Mati Somp
on 5 Oct 2020

simple and fast

function coded = caesar(txt,nr)

char_set=char(32):char(126);

char_set3=[char_set char_set char_set];

coded = char_set3(txt+64+nr-floor(nr/95)*95);

end

Walter Roberson
on 6 Oct 2020

Dhinesh Kumar
on 11 Oct 2020

function txt = caesar(txt,key)

txt = double(txt) + key;

first = double(' ');

last = double('~');

% use mod to shift the characters - notice the + 1

% this is a common error and results in shifts

% being off by 1

txt = char(mod(txt - first,last - first + 1) + first);

end

This also helps to solve the problem. Try it

XINYI CAI
on 15 Mar 2021

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

Start Hunting!