28

ここで構文を強調表示した問題のコード: 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>

ご覧のように、文字どおり 1 行を使用して、プロトタイピングのように String オブジェクトにメソッドをアタッチしています。以前にセットアップした map() メソッドがあります (そのコードが完全に機能することは確かです。単純に配列内の各要素を反復処理し、パラメーターで指定された関数を適用する) 文字列内の各文字を調べて、文字列を rot13 された対応する文字列に変換するための適切な計算を行います。私は悲しいことに間違っていました。誰かが私がどこを間違えたかを見つけることができますか?

4

17 に答える 17

77

スーパーショートを使用できます:

s.replace(/[a-zA-Z]/g,function(c){return String.fromCharCode((c<="Z"?90:122)>=(c=c.charCodeAt(0)+13)?c:c-26);});
于 2009-03-06T04:32:26.870 に答える
20

replace関数とindexOf関数を使用したソリューションは次のとおりです。

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

これは次のもので構成されています。

  • /[A-Z]/gi文字のみに一致する正規表現
  • replaceこれらの文字を置き換えるために使用されます
  • アロー関数として書かれた置換関数
  • indexOf文字を数値ルックアップインデックスに変換することです
  • 置換配列のインデックスを検索して完了です
于 2015-02-13T00:04:39.607 に答える
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 :)")));

于 2013-04-01T17:06:07.437 に答える
12

それがさらに短く、より理解しやすく/論理的であるという理由だけで:

function rot13(s) {
  return s.replace( /[A-Za-z]/g , function(c) {
    return String.fromCharCode( c.charCodeAt(0) + ( c.toUpperCase() <= "M" ? 13 : -13 ) );
  } );
}
于 2013-01-27T22:47:11.623 に答える
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]"
于 2014-03-13T01:07:13.290 に答える
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

0 から始まるインデックスと 1 から始まるインデックスを組み合わせて負けます。私はネットスケープのせいです。

于 2009-03-06T04:31:25.810 に答える
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.');

于 2014-01-05T05:09:35.373 に答える
2

私のゴルフ バージョンは 82 バイトの長さです (対 Ben Albert は 35% 重いですが、インスピレーションを与えてくれました):

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

違い:

  • 大文字と小文字を区別せず、英語のアルファベットのみをキャッチします。
  • return と中かっこのないアロー関数。
  • charCodeAt からパラメーターを削除します。
  • 文字列を挿入したコードに対してテストします。
  • +13-26=-13 を実行しています。
  • 大文字 ( &95) を 77 (78+13=91、オーバーフロー) に対してテストします。

追加: 数字に対して ROT5 を実行する場合は、次を追加します。 .replace(/\d/gi,c=>(c>4?-5:5)+c*1)

于 2017-01-03T03:03:47.537 に答える
2

まだ拡張の余地があります。チェック (c<="Z") は、実際にはコードポイント (後で必要になります) に対するチェックです。

// vs Kevin M's style : 115 chars (vs 116)
// nodejs Buffer で 102 chars (下記参照)

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)
//nodejs バッファーを使用した場合は 93 文字 (以下を参照)

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
于 2015-01-31T15:23:28.377 に答える
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'
于 2014-06-16T10:39:18.360 に答える
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.

于 2018-10-25T02:43:37.287 に答える
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('');
 }
于 2009-03-06T16:06:37.013 に答える
0

@ben-alpert の回答の 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'
于 2015-09-28T19:58:14.760 に答える