简体   繁体   中英

Trying to reconvert this caesar cipher arr into characters via .charCodeAt in javascript

I'm working on a Caesar cipher problem and have been trucking away but definitely am stuck trying to reconvert this array back into characters.

I tried things like:

document.write(eval('String.fromCharCode('++')'));

and

document.write(String.fromCharCode.apply(null, solved));

and several others with no luck. Any thoughts? I'd really like to avoid going back to the drawing board since this is so close...

Thanks for looking!

 function rot13(str) { // LBH QVQ VG! var solved = []; var arr = str.split(""); for (var i=0; i<arr.length; i++) { solved.push(arr[i].charCodeAt(0)); if (solved[i]>65 && solved[i]<91){ solved[i]-=13; } String.fromCharCode(solved[i]); } return solved.join("");} rot13("SERR PBQR PNZC"); 

You can't subtract 13 unconditionally: you have to check to see if the code point is below 78 or not. (if it's below 78, then you need to add 13 instead of subtract, or you'll get incorrect characters at the end)

document.write is document.wrong. Use something more modern and less prone to doing confusing things. This function tries to write to the current document. If the document has already been processed, the document will be replaced with a blank one with your argument. You don't want that; use the proper DOM methods instead. (don't use eval either)

You're doing

String.fromCharCode(solved[i]);

but that's a standalone line which doesn't do anything - you probably meant to assign its result to solved[i] .

To avoid confusing yourself, probably don't push to the solved array until you actually have a solved character.

 function rot13(str) { const solved = []; const arr = str.split(""); for (let i = 0; i < arr.length; i++) { const initialCharCode = arr[i].charCodeAt(0); if (initialCharCode > 65 && initialCharCode < 91) { const rotCode = initialCharCode < 78 ? initialCharCode + 13 : initialCharCode - 13; solved.push(String.fromCharCode(rotCode)); } else { solved.push(String.fromCharCode(initialCharCode)); } } return solved.join(""); } console.log(rot13("SERR PBQR PNZC")); 

Sorry if trying to figure out my attempt is more headache than going back to the drawing board:

 function rot13(str) { const a = 'A'.charCodeAt(0); return str.split('') .map(c => c >= 'A' && c <= 'Z' ? String.fromCharCode((c.charCodeAt(0) - a + 13) % 26 + a) : c) .join(''); } console.log(rot13("SERR PBQR PNZC")) console.log(rot13('LBH QVQ VG!')) 

Like @CertainPerformance said, the main problem with your code is that you're blindly subtracting 13 (you have to subtract and rotate). I chose to rotate the character using modulus though, rather than introduce another magic number, but maybe modulus isn't as clear, doh.

Another idea in the code above is to use map so I'm guaranteed an output the same size as the input. If I'm constructing the result string with push , I'd have to be a bit more careful than I can be with map .

A final thing is I use clang-format to format my code when I save it (in VS Code/Atom/Vim). That instantly makes the code tidy, which helps me catch bugs.

Hope something here helps, sorry if all of this hinders.

Here's a version that handles both upper and lower case:

function rot13(s) {
  return s.split('').map(c => {
    var cc = c.charCodeAt(0);

    if ('A' <= c && c <= 'Z')
      cc = ((cc - 65 + 13) % 26) + 65;
    else if ('a' <= c && c <= 'z')
      cc = ((cc - 97 + 13) % 26) + 97;

    return String.fromCharCode(cc);
  }).join('');
}

Plunker here: http://plnkr.co/edit/Yn1scOO8iwfyQCgOQuHA?p=preview

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM