シーザーのパスワード|プログラマー


問題に答える

シーザーパスワード(Lv.1)


質問する


1つの暗号化方法は、1つの文の各アルファベットを一定の距離で伸ばし、別のアルファベットに変換することです.例えば、「AB」は1で「BC」、3で「DE」を表す.「z」が1に等しいと「a」になります.文字列sと距離nを入力し、sがnの暗号文の関数を生成し、ソリューションを完了します.

せいげんじょうけん

  • スペースはいくら押しても空いています.
  • sには、小文字、大文字、スペースのみが含まれます.
  • sの長さは8000未満です.
  • nは1以上25以下の自然数です.
  • I/O例


    snresult"AB"1"BC""z"1"a""a B z"4"e F d"

    私の答え


    問題を理解する


    1.文字列の各文字を次のn文字に戻す



    2.n移動の値がZまたはZを超えた後、AまたはAから計算を継続する



    3.スペース(space)も厳格な文字で、データ改ざんなしで直接返す



    アルファベット順の配列を値として取り戻すにはどうすればいいですか?
    Event Handlerで使用されているkeycode値のように、アルファベット値を格納(またはアドレス)するコードはありますか?

    String.prototype.charCodeAt()


    charcodeatメソッドは、文字列内の特定のインデックスの値をUTF-16コードに返します.アルファベットのUTF-16コードが順番に並んでいる場合は、コード値にnを加えればよい.では、UTF-16コードを文字に戻すにはどうすればいいのでしょうか.
    UTF-16テーブルは以下のリンクで表示できます
    🔗 UTF-16 Table

    String.fromCharCode()


    UTF-16コードがパラメータとして渡された場合、その文字を返す方法.
    上記の2つの方法を核心機能としてコードを記述する.

    メソッドテスト

    const upperCases = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    const lowerCases = 'abcdefghijklmnopqrstuvwxyz';
    
    function solutionTest(phrase) {
      const arr = [];
      const arr2 = [];
      for (let i = 0; i < phrase.length; i++) {
        arr.push(phrase.charCodeAt(i));
        arr2.push(String.fromCharCode(phrase.charCodeAt(i + 1)));
        // let nextWord = phrase.charCodeAt(i+1);
        // arr2.push(nextWord)
      }
      return `${arr}\n${arr2.join('')}`;
    }
    
    console.log(solutionTest(upperCases));
    // 65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90
    // BCDEFGHIJKLMNOPQRSTUVWXYZ
    console.log(solutionTest(lowerCases));
    // 97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122
    // bcdefghijklmnopqrstuvwxyz
  • UTFコードへの変換を確認し、UTFコードに値を付けて文字で返すことができます.
  • ですが、大文字Zと小文字Zで正しい戻り値がないことがわかります.UTFテーブルから分かるように、大文字の範囲は65~90、小文字の範囲は97~122である.
  • したがって、符号値にnを加えた値が大文字である場合、90、小文字が122を超える場合、z->a符号を再び減算し、となる.

    機能実装

    const upperCases = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    const lowerCases = 'abcdefghijklmnopqrstuvwxyz';
    
    function solution(str, num) {
      let temp = [];
    
      // 각 자리를 순회하며 charCode 알아냄
      for (let i = 0; i < str.length; i++) {
        temp.push(str.charCodeAt(i));
      }
    
      let newTemp = temp.map(e => {
        // 대문자는 65 ~ 90까지
        // 소문자는 97 ~ 122까지
        // 공백(space)은 32
        if (e === 32) return 32; // Guard Clause
        if (e >= 97 && e + num <= 122) {return e + num} // 소문자 걸러내기
        if (e + num > 90) {
          return e + num - 26;
        // default = charCode + num
        } else {
          return e + num;
        }
      });
    
      // fromCharCode로 charCode로부터 해당 문자를 받아옴
      return newTemp.map(e => {
        return String.fromCharCode(e)
      }).join('');
    }
  • 文字の各文字をUTFコードに変換する一時記憶
  • .
    マッピング
  • コード配列
  • 値が空(コード:32)の場合、
  • が保持されます.
  • この値が97より大きく、n値が122より大きい場合、戻りコード+n値(ほとんどの小文字)
  • が返される.
  • この値にnを加える値が90を超えると、合計から26(合計がZまたはZを超えるとA、A)
  • が減算.
  • の他の値については、defaultで合計
  • を返します.
  • ビットプロセスを経たコードシーケンスを文字列に変換し、
  • を返す.

    完了

    const testStr1 = 'LcxcUetkrv ku c Itgcv Ncpiwcig';
    const testStr2 = 'Nz obnf jt Xpolppl Mff';
    
    function solution(str, num) {
      let charCodes = [];
      for (let i = 0; i < str.length; i++) {
        charCodes.push(str.charCodeAt(i));
      }
      let result = charCodes.map(e => {
        if (e === 32) return e;
        if (e >= 97 && e + num <= 122) {
          return e + num
        } else if (e + num > 90) {
          return e + num - 26
        } else {
          return e + num
        }
      });
      return result.map(e => {
        return String.fromCharCode(e)
      }).join('');
    }
    
    // RESULT
    console.log(solution(testStr1, -2));
    // "JavaScript is a Great Language"
    console.log(solution(testStr2, -1));
    // "My name is Wonkook Lee"
    大文字と小文字を区別することで条件文が複雑になるのが残念です.
    上記プールは位置移動しか解決できないため,移動値をAからZに負の値で移動することは実現していない.(+10分)