有问题的代码,语法高亮显示在这里: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>
正如你所看到的,使用一个单独的行来将一个方法附加到String对象的一个原型,我有一个我之前设置的map()方法(我确信这个代码完美无缺) ;它只是迭代数组中的每个元素并应用参数中指定的函数)遍历字符串中的每个字符并执行我认为正确的计算,将字符串转换为它的rot13'd对应物。我很遗憾地错了。任何人都可以找到我出错的地方吗?
答案 0 :(得分:70)
您可以使用超级短片:
s.replace(/[a-zA-Z]/g,function(c){return String.fromCharCode((c<="Z"?90:122)>=(c=c.charCodeAt(0)+13)?c:c-26);});
答案 1 :(得分: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 :)")));
答案 2 :(得分:15)
以下是使用replace
,indexOf
和charAt
函数的解决方案:
function rot13(s) {
return s.replace(/[A-Za-z]/g, function (c) {
return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".charAt(
"NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm".indexOf(c)
);
} );
}
尽管其他答案越来越短&#39; (即较低的字符数),我认为这个答案更容易理解。
答案 3 :(得分:11)
只是因为它更短,更易理解/更符合逻辑:
function rot13(s) {
return s.replace( /[A-Za-z]/g , function(c) {
return String.fromCharCode( c.charCodeAt(0) + ( c.toUpperCase() <= "M" ? 13 : -13 ) );
} );
}
答案 4 :(得分: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)}
它仍然只有116个字节。非常小而且非常聪明。
(对不起,完整的答案发布;我仍然缺少50个代表发布此评论作为Kevin的优秀答案。)
答案 5 :(得分: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
为输入混合零基和一基指数。我责怪Netscape。
答案 6 :(得分: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);
});
}
显示它正在运作的一个例子:
rot13('[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]')
"[nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM]"
rot13(rot13('[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]'))
"[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]"
答案 7 :(得分:4)
单行重量为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.');
答案 8 :(得分:3)
%26应该在+ 13之后吗?
k = ((_.toLowerCase().charCodeAt(0) - 96) + 13) % 26;
答案 9 :(得分:2)
仍然有增强的空间,检查(c&lt; =“Z”)实际上是对码点的检查(我们稍后需要),遵循这个想法让我们获胜!
//与Kevin M的风格:115个字符(vs 116)
//带有nodejs缓冲区的102个字符(见下文)
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)}
//与Ben Alpert风格:107个字符(vs 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中,您可以使用Buffer来转换/序列化代码点,例如:
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
答案 10 :(得分:2)
在这里结合各种技术,我想出了这个78字符的JavaScript ES6函数,它可以在Node上运行:
rot13=s=>s.replace(/[a-z]/ig,c=>Buffer([((d=Buffer(c)[0])&95)<78?d+13:d-13]));
答案 11 :(得分:2)
我的高尔夫版本长度为82个字节(与Ben Albert相比,重35%,但我的灵感来自于此):
S.replace(/[a-z]/gi,c=>String.fromCharCode((c=c.charCodeAt())+((c&95)>77?-13:13)))
的差异:
&95
)对77(78 + 13 = 91,溢出)。额外:如果您想对数字执行ROT5,请添加:
.replace(/\d/gi,c=>(c>4?-5:5)+c*1)
答案 12 :(得分:1)
这是一个执行ROT-n字母替换的JavaScript库:https://github.com/mathiasbynens/rot
rot 是一个执行旋转字母替换的JavaScript库。它可用于将输入字符串中的任何ASCII字母移动字母表中给定数量的位置。至ROT-13字符串
'abc'
,例如:// ROT-13 is the default rot('abc'); // → 'nop' // Or, specify `13` explicitly: rot('abc', 13); // → 'nop'
答案 13 :(得分:1)
这是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。
答案 14 :(得分:1)
这绝不是试图在这里与优秀的东西竞争,因为你看我无法发表评论但是我有自己的新手尝试在JS中编写这个并在我阅读更优雅的解决方案之前让它工作在这里 - 我将在这里分享。
我尝试使用indexOf
,switch
,String.fromCharCode()
和CharCodeAt()
添加13。它们太长了 - 这个中的辅助函数是不必要的,但这是我最短的:)
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 :(得分:0)
@ ben-alpert的answer的CoffeeScript版本:
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'
答案 16 :(得分:0)
虽然我真的喜欢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)
我最喜欢的,易于理解的ROT13号决定版本
function rot13(message) {
var a = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
var b = "nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM"
return message.replace(/[a-z]/gi, c => b[a.indexOf(c)])
}
a
-经典字母,b
-带有第13个替换字符的词典,return
个结果,带有简单的RegEx替换符