Codesignal Solution: caesarian
Caesarian shift (Caesar cipher) is a method used in cryptography where a string message
is encrypted by shifting the letters n
times.
You are given an integer n
, which can be positive, negative or zero. Positive values indicate right shifts, and negative values indicate left shifts.
Given a message
and n
, return message
encrypted by the shift n
.
Example

For
message = "abc"
andn = 3
, the output should becaesarian(message, n) = "def"
."a"
, shifted to the right3
times, becomes"d"
,"b"
becomes"e"
and"c"
becomes"f"
. 
For
message = "egg"
andn = 1
, the output should becaesarian(message, n) = "dff"
.
Input/Output
 [time limit] 4000ms (js)

[input] string message
The message to be encrypted.
Constraints:
0 ≤ message.length ≤ 500
. 
[input] integer n
The shift value.
Constraints:
2 · 10^{9} ≤ n ≤ 2 · 10^{9}
. 
[output] string
Encrypted message.
Solution
I worked on a Caesar Chiffre Decoder, which probabilistically guesses the right key. For this problem, we get the key and simply have to encode a given message. So the hard part is again, how can we find a minimalistic solution. I tried different things, but I'll explain only my final submission here. In order to loop over the ASCII values of a string in JavaScript, it's a fuss of function calls like String.fromCharCode()
, charCodeAt()
and so on. A nice alternative is using the Buffer
object, which has a copy constructor for strings and can be casted to Uint8Array
like this:
new Uint8Array(new Buffer("hello"))
Buffer doesn't require the newkeyword and also the explicit call to Uint8Array
is not needed, since there is the spreadsyntax in ES6, which minimizes the code to:
[...Buffer("hello")]
Now that we have an array of the ASCII values of the string, we can map
the values in order to shift them accoring to the given offset:
[...Buffer("hello")].map(x => f(x))
We now need to map the old ASCIIvalues to the new shifted values. In a perfectly aligned world, we would simply subtract 97 from the value in order to make 'a' zero, add the required shift and readd the subtracted 97 after taking the modulo for the given congruence relation.
\[f(x) = (x  97 + n) \bmod 26 + 97 \]
As the shift parameter \(n\) can become quite small, we need to shrink it as the JavaScript modulo operator is not the same as the mathematical modulo. We can move in the modulo relaton, which eliminates the 97, which becomes +7 and n % 26
gives us the interval \([25, 25]\), which is okay because we add it to lowercase letters afterwards  which are always \(\geq 97\):
\[f(x) = (x + 7 + n\bmod 26) \bmod 26 + 97 \]
Bringing together these two pieces leads to the following solution:
b=Buffer caesarian = (m, n) => ""+b([...b(m)].map(x => (n % 26 + x + 7) % 26 + 97))