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

IT技术 javascript algorithm rot13
2021-01-28 02:12:55

有问题的代码在此处突出显示语法:通过 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>

正如您所看到的,使用非常简单的一行将方法附加到 String 对象的原型,我有一个我之前设置的 map() 方法(我确信该代码可以完美运行;它只是迭代数组中的每个元素并应用参数中指定的函数)遍历字符串中的每个字符并执行我认为正确的计算以将字符串转换为它的 rot13 对应物。可惜我错了。任何人都可以发现我哪里出错了吗?

6个回答

你可以使用超短:

s.replace(/[a-zA-Z]/g,function(c){return String.fromCharCode((c<="Z"?90:122)>=(c=c.charCodeAt(0)+13)?c:c-26);});
@Howard rot13.com伙计们忘记检查他们的“改进”,这个公式适用于rot13,但他们决定实施rot1并最多rot25不考虑太多,结果他们失去了rot13- 可逆性的主要要点:) 所以,请记住, - 他们的解决方案仅适用于rot13
2021-03-29 02:12:55
由于这似乎是一个高尔夫球的答案:您可以通过替换/[A-Za-z]/g/[A-Z]/gi或 来缩短两个字符/[a-z]/gi2009 年的 JavaScript 中不存在不区分大小写的 RegExp 吗?
2021-04-01 02:12:55
刚刚发现您的代码现在正在 rot13.com 上使用
2021-04-09 02:12:55

这是使用replaceindexOf功能的解决方案

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

这是由:

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

这给出了正确的结果。

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 :)")));

@Hexagon - 没有接受的答案? Zibri 的这里似乎工作
2021-03-18 02:12:55
@ruffin - 这在包含下划线“_”的字符串上失败
2021-03-21 02:12:55
从这里的许多答案来看,我首先尝试了这个,并且效果很好,它与 PHP 的str_rot13().
2021-03-31 02:12:55

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

function rot13(s) {
  return s.replace( /[A-Za-z]/g , function(c) {
    return String.fromCharCode( c.charCodeAt(0) + ( c.toUpperCase() <= "M" ? 13 : -13 ) );
  } );
}
@Rhymoid 如果你的意思是[A-z]错了”,那么我(再次可耻地)同意......我[A-z]从(非常有用的)网站 www.w3schools.com 获得,但是当我测试它时,我发现这个范围还包含一些特殊的字符,比如反斜杠和下划线……所以我把它改成了[A-Za-z].
2021-03-19 02:12:55
哎哟! 惭愧,我应该做这个简单的测试。只需要小的更正:'<=' 而不是 '<'。现在它工作正常!
2021-03-21 02:12:55
/[A-z]/ 对我来说也很可疑。
2021-03-25 02:12:55
值得注意的是,如果输入不是严格按字母顺序排列的,原始函数就会停止,而这不会。(就我而言,这个实际上更可取)
2021-04-05 02:12:55

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

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

(对于完整的答案发布感到抱歉;我仍然缺少 50 位代表将其发布为对凯文出色答案的评论。)

+1 出色的捕捉伦敦!我会更新我的答案以反映您的更改。
2021-04-13 02:12:55