代码之家  ›  专栏  ›  技术社区  ›  Hexagon Theory

JavaScript中rot13的单行实现哪里出了问题?

  •  23
  • Hexagon Theory  · 技术社区  · 16 年前

    via 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>
    

    17 回复  |  直到 6 年前
        1
  •  75
  •   Sophie Alpert    16 年前

    您可以使用超短:

    s.replace(/[a-zA-Z]/g,function(c){return String.fromCharCode((c<="Z"?90:122)>=(c=c.charCodeAt(0)+13)?c:c-26);});
    
        2
  •  19
  •   Stephen Quan    5 年前

    replace indexOf 功能:

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

    这包括:

    • /[A-Z]/gi 仅匹配字符的正则表达式
    • 用于替换这些字符
    • 作为箭头函数编写的替换函数
    • 索引 是将字符转换为数字查找索引
    • 我们在替换数组中查找索引,就完成了
        3
  •  16
  •   Zibri    6 年前

    这给出了正确的结果。

    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 :)")));
        4
  •  12
  •   Herman    11 年前

    只是因为它更简短,也更容易理解/逻辑:

    function rot13(s) {
      return s.replace( /[A-Za-z]/g , function(c) {
        return String.fromCharCode( c.charCodeAt(0) + ( c.toUpperCase() <= "M" ? 13 : -13 ) );
      } );
    }
    
        5
  •  10
  •   Lonnon Foster    11 年前

    [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)}
    

    仍然只有116字节。非常小而且非常聪明。

        6
  •  5
  •   Paul    11 年前
    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
    

    混合基于零和基于一的损失指数。我责备网景。

        7
  •  5
  •   Vjeux    11 年前

    这是一个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);
      });
    }
    

    以及一个显示其工作的示例:

    rot13('[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]')
    "[nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM]"
    rot13(rot13('[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]'))
    "[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]"
    
        8
  •  4
  •   Kevin M    10 年前

    一个重量为116字节的衬里:

    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)}
    

    r('The Quick Brown Fox Jumps Over The Lazy Dog.');

        9
  •  3
  •   cobbal    16 年前

    %26应该在+13之后吗?

    k = ((_.toLowerCase().charCodeAt(0) - 96) + 13) % 26;
    
        10
  •  2
  •   131    10 年前

    仍有改进、检查的余地(c<=”Z”)实际上是对代码点(我们稍后需要)的检查,遵循这个想法我们会赢!

    //与凯文M的风格:115个字符(对116个)
    //102个字符和nodejs缓冲区(见下文)

    function r(a,b){return++b?String.fromCharCode(((a=a.charCodeAt())<91?78:110)>a?a+13:a-13):a.replace(/[a-zA-Z]/g,r)}
    //nodejs style
    function r(a,b){return++b?Buffer([((a=Buffer(a)[0])<91?78:110)>a?a+13:a-13]):a.replace(/[a-zA-Z]/g,r)}
    

    //与本·阿尔伯特风格的对比:107个字符(与112个字符)
    //93个字符和nodejs缓冲区(见下文)

    s.replace(/[a-zA-Z]/g,function(a){return String.fromCharCode(((a=a.charCodeAt())<91?78:110)>a?a+13:a-13)});
    //nodejs style
    s.replace(/[a-zA-Z]/g,function(a){return Buffer([((a=Buffer(a)[0])<91?78:110)>a?a+13:a-13])})
    

    String.prototype.rot13 = function() {
      return this.replace(/[a-zA-Z]/g, function(a){
        return String.fromCharCode(((a=a.charCodeAt())<91?78:110)>a?a+13:a-13);
      });
    }
    

    在nodejs中,您可以使用缓冲区强制转换/序列化代码点,例如:

    var a=65;
    ""+Buffer([a])           == "A" // note that the cast is done automatically if needed
    String.fromCharCode(a)   == "A"
    
    var b="A";
    Buffer(a)[0]             == 65
    a.charCodeAt()           == 65
    
        11
  •  2
  •   ESL    8 年前

    我的golfed版本长82字节(与Ben Albert相比,Ben Albert重35%,但启发了我):

    S.replace(/[a-z]/gi,c=>String.fromCharCode((c=c.charCodeAt())+((c&95)>77?-13:13)))

    • 不区分大小写,仅捕获英文字母。
    • 箭头函数不带返回和大括号。
    • 从charCodeAt中删除参数。
    • 用字符串代替代码进行测试。
    • &95 )对77(78+13=91,溢出)。

    .replace(/\d/gi,c=>(c>4?-5:5)+c*1)

        12
  •  2
  •   jrbedard    8 年前

    rot13=s=>s.replace(/[a-z]/ig,c=>Buffer([((d=Buffer(c)[0])&95)<78?d+13:d-13]));
    
        13
  •  1
  •   Mathias Bynens    11 年前

    下面是一个执行ROT-n字母替换的JavaScript库: https://github.com/mathiasbynens/rot

    腐烂 是一个执行旋转字母替换的JavaScript库。它可以用于将输入字符串中的任何ASCII字母在字母表中移动给定数量的位置。弄坏绳子 'abc' ,例如:

    // ROT-13 is the default
    rot('abc');
    // → 'nop'
    
    // Or, specify `13` explicitly:
    rot('abc', 13);
    // → 'nop'
    
        14
  •  1
  •   isosceles    9 年前

    这绝不是在试图与这里的优秀内容竞争,正如你所看到的,我无法评论,但我有自己的新手尝试用JS编写这篇文章,并在我阅读更多优雅的解决方案之前将其付诸实施——我将在这里分享。

    indexOf A. switch ,加入13,加入— String.fromCharCode() CharCodeAt() . 它们太长了-这一个中的helper函数是不必要的,但这是我最短的:)

    function rot13(string) { 
      var result = '', 
          store,
          str = string.toLowerCase();  
    
      //helper function
      function strgBreak(a){
        var result = [];
        return result = a.split('');
      }
    
      //rot13 arrays
      var alphArr = strgBreak('abcdefghijklmnopqrstuvwxyz');
      var inverseArr = strgBreak('nopqrstuvwxyzabcdefghijklm');
    
     for ( var i = 0; i < str.length; i++ ) {
         if (alphArr.indexOf( str[i] ) !== -1) {
            result += inverseArr[ alphArr.indexOf( str[i] ) ];
        } else result += str[i];
      }
     return result.toUpperCase(); 
    }
    
        15
  •  1
  •   Grant Miller    6 年前

    以下是ROT13替换密码的现代方法:

    const ROT13 = s =>
      s.replace(/[a-z]/gi, c =>
        String.fromCharCode(c.charCodeAt() + 13 - 26 * /[n-z]/i.test(c)));
    
    console.log(ROT13('The quick brown fox jumps over 13 lazy dogs.'));

    上述测试用例的结果为:

    Gur dhvpx oebja sbk whzcf bire 13 ynml qbtf。

        16
  •  0
  •   Hexagon Theory    16 年前

    而我 真正地 像RegEx解决方案一样,我主要负责这个项目,看看是否可以完成它。很高兴地报告,我终于做到了:

    String.prototype.rot13 = rot13 = function(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('');
     }
    
        17
  •  0
  •   Community CDub    8 年前

    咖啡脚本版本的@ben alpert's answer :

    string.replace /[a-zA-Z]/g, (c) -> String.fromCharCode if (if c <= 'Z' then 90 else 122) >= (c = c.charCodeAt(0) + 13) then c else c - 26
    

    或作为功能:

    ROT13 = (string) -> string.replace /[a-zA-Z]/g, (c) -> String.fromCharCode if (if c <= 'Z' then 90 else 122) >= (c = c.charCodeAt(0) + 13) then c else c - 26
    ROT13('asd') # Returns: 'nfq'
    
        18
  •  0
  •   krolovolk    5 年前

    function rot13(message) {
      var a = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
      var b = "nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM"
      return message.replace(/[a-z]/gi, c => b[a.indexOf(c)])
    }
    

    a -经典字母, b return 简单正则表达式替换的结果