我在JavaScript中的单行实现rot13哪里出错了?

Hex*_*ory 24 javascript algorithm rot13

有问题的代码,语法突出显示在这里:通过Friendpaste

rot13.js:

<script>
String.prototype.rot13 = rot13 = function(s)
 {
    return (s = (s) ? s : this).split('').map(function(_)
     {
        if (!_.match(/[A-Za-z]/)) return _;
        c = Math.floor(_.charCodeAt(0) / 97);
        k = (_.toLowerCase().charCodeAt(0) - 96) % 26 + 13;
        return String.fromCharCode(k + ((c == 0) ? 64 : 96));
     }).join('');
 };
</script>
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,使用一个单独的行来将一个方法附加到String对象的原型,我有一个我之前设置的map()方法(我确信这个代码完美无缺;它只是简单迭代数组中的每个元素并应用参数中指定的函数)遍历字符串中的每个字符并执行我认为正确的计算,将字符串转换为它的rot13'd对应项.我很遗憾地错了.任何人都可以找到我错的地方吗?

Sop*_*ert 73

你可以使用超短:

s.replace(/[a-zA-Z]/g,function(c){return String.fromCharCode((c<="Z"?90:122)>=(c=c.charCodeAt(0)+13)?c:c-26);});
Run Code Online (Sandbox Code Playgroud)

  • 刚发现您的代码现在正在rot13.com上使用 (8认同)
  • 由于这似乎是一个解决办法:您可以通过将`/ [A-Za-z] / g`替换为`/ [AZ] / gi或`/ [az] / gi`来使其短两个字符。2009年JavaScript中不存在不区分大小写的RegExp吗? (3认同)

Zib*_*bri 16

这给出了正确的结果.

function rot13(s)
 {
    return (s ? s : this).split('').map(function(_)
     {
        if (!_.match(/[A-Za-z]/)) return _;
        c = Math.floor(_.charCodeAt(0) / 97);
        k = (_.toLowerCase().charCodeAt(0) - 83) % 26 || 26;
        return String.fromCharCode(k + ((c == 0) ? 64 : 96));
     }).join('');
 }
 
 alert(rot13(rot13("Mark this as accepted answer :)")));
Run Code Online (Sandbox Code Playgroud)


Ste*_*uan 15

下面是一个使用的解决方案replace,indexOf并且/[A-Z]/gi功能:

function rot13(s) {
  return s.replace(/[A-Z]/gi, c =>
    "NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm"[
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".indexOf(c) ] )
}
Run Code Online (Sandbox Code Playgroud)

尽管其他答案"更短"(即较低的字符数),我认为这个答案更容易理解.


Her*_*man 11

仅仅因为它更短,也更易理解/合乎逻辑:

function rot13(s) {
  return s.replace( /[A-Za-z]/g , function(c) {
    return String.fromCharCode( c.charCodeAt(0) + ( c.toUpperCase() <= "M" ? 13 : -13 ) );
  } );
}
Run Code Online (Sandbox Code Playgroud)


Lon*_*ter 9

Kevin M的解决方案紧凑而优雅.但是它有一个小错误:与replace函数一起使用的正则表达式不会将替换限制为字母字符.该[A-z]字符范围包括标点字符([\] ^ _ `),这将被交换信件时,他们应该被单独留在家中.

固定版本如下所示:

function r(a,b){return++b?String.fromCharCode((a<"["?91:123)>(a=a.charCodeAt()+13)?a:a-26):a.replace(/[a-zA-Z]/g,r)}
Run Code Online (Sandbox Code Playgroud)

它仍然只有116个字节.非常小,非常聪明.

(对不起,完整的答案发布;我仍然缺少50个代表发布此评论作为Kevin的优秀答案.)


Spa*_*arr 5

var rot13 = String.prototype.rot13 = function(s)
{
  return (s = (s) ? s : this).split('').map(function(_)
  {
    if (!_.match(/[A-Za-z]/)) return _;
    c = _.charCodeAt(0)>=96;
    k = (_.toLowerCase().charCodeAt(0) - 96 + 12) % 26 + 1;
    return String.fromCharCode(k + (c ? 96 : 64));
  }
  ).join('');
};

alert('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.rot13());
yields nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM
Run Code Online (Sandbox Code Playgroud)

为损失混合零基和一基指数.我怪Netscape.


Vje*_*eux 5

这是一个有80列的版本,不会更新string.prototype,缩进的程度也很短。

function rot13(str) {
  return str.replace(/[a-zA-Z]/g, function(chr) {
    var start = chr <= 'Z' ? 65 : 97;
    return String.fromCharCode(start + (chr.charCodeAt(0) - start + 13) % 26);
  });
}
Run Code Online (Sandbox Code Playgroud)

一个显示它正在工作的示例:

rot13('[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]')
"[nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM]"
rot13(rot13('[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]'))
"[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]"
Run Code Online (Sandbox Code Playgroud)