DEV Community

Discussion on: Public Solving: Caesar decipher in JavaScript

Collapse
 
lexlohr profile image
Alex Lohr

An interesting property of latin alphabetical characters is that their 5th bit (32) being set or unset is the only difference between a large or a small character and the 6th bit (64) is set for both. We can also employ binary operations like | and & to filter certain bits.

characterCode & 31 = 1 for 'A', 2 for 'B'...
characterCode & 96 = 64 for upper case, 96 for lower case

That allows us to create a letterShift function that returns a function that directly works as a callback to string. replace.

const letterShift = (shift) => (letter) => {
  const charCode = letter.charCodeAt(0)
  // 64 for upper case, 96 for lower case
  const casePart = charCode & 96
  // 1 for a, 2 for b, ...
  const charPart = charCode & 31
  // use modulo for wraparound
  const shiftedCharPart = ((charPart - 1 + shift) % 26) + 1
  return String.fromCharCode(casePart | shiftedCharPart)
}
Enter fullscreen mode Exit fullscreen mode

P.S. I wrote this on my cellphone, so there are probably a few typos in there.

Collapse
 
dailydevtips1 profile image
Chris Bongers

That is amazing, actually didn't dive that deep into it!
So really glad to find out we can use it as a two part element