2

I found this ingenious caesar cipher solution on codefights. I'm trying to understand what the buffer is doing here.

b=Buffer
caesarian = (m, n) =>
  "" + b([...b(m)].map(x => (n % 26 + x + 7) % 26 + 97))

Can empty strings concatenate with typed arrays like that?

  • Strings? Typed arrays? Where do you see those? Please show an example invocation and what you don't understand about it or how you'd have written it without buffers. – Bergi Oct 16 '16 at 21:30
  • Doesn't the Buffer constructor create a typed array? I did not write this. I came across it and I'm trying to understand it. –  Oct 16 '16 at 21:32
  • 1
    This is a Node.js `Buffer`, right? you should use the Node.js tag. – joews Oct 16 '16 at 21:33
  • @epiqueras [No](https://nodejs.org/api/buffer.html#buffer_new_buffer_string_encoding)? – Bergi Oct 16 '16 at 21:35

1 Answers1

3

Iterating a Node.js Buffer yields its data one byte at a time. For a Buffer (with the default encoding of utf8) that contains alphanumeric characters, that's the same as getting each char's ASCII code:

[...Buffer("hello")] // [ 104, 101, 108, 108, 111 ]

(n % 26 + x + 7) % 26 + 97) is the Caesar cipher arithmetic over ASCII - I guess you're familiar with this part.

So, this chunk interprets the String as an array of ASCII codes and transforms them to their corresponding outputs:

[...b(m)].map(x => (n % 26 + x + 7) % 26 + 97))

You can initialise a Buffer with an array of byte values:

Buffer([97]) // <Buffer 61>

You can get the String representation of anything in JavaScript by concatentating it with an empty String, so "" + b([97]) is the same as Buffer([97]).toString(). Buffer#toString interprets the stored bytes as unicode characters:

"" + Buffer([97]) // 'a'

Therefore the point of the outer "" + b(/* ... */) is to turn the manipulated ASCII codes back into alphanumeric characters for display.

joews
  • 29,767
  • 10
  • 79
  • 91