一个单词,只有每第二个字母破译

发布于 2025-01-19 02:28:27 字数 746 浏览 3 评论 0原文

因此,我正在发挥作用,以破译Rot13或Caesar密码的变体。但是由于某种原因,它只会每第二个字母解密...我不知道要更改或做什么。谢谢

function rot13(str) {
  let regexp = /\w/gi;
  let obj = {
    "A": "N",
    "B": "O",
    "C": "P",
    "D": "Q",
    "E": "R",
    "F": "S",
    "G": "T",
    "H": "U",
    "I": "V",
    "J": "W",
    "K": "X",
    "L": "Y",
    "M": "Z",
    "N": "A",
    "O": "B",
    "P": "C",
    "Q": "D",
    "R": "E",
    "S": "F",
    "T": "G",
    "U": "H",
    "V": "I",
    "W": "J",
    "X": "K",
    "Y": "L",
    "Y": "M",
  };
  for (let i = 0; i < str.length; i++) {
    if (regexp.test(str[i])) {
      str = str.replace(str[i], obj[str[i]]);  
    }
  };
  return str;
}
console.log(rot13("SERR"));

//output: FEER

//wanted output: FREE

So I'm making a function to decipher rot13 or a variant of caesar's cipher. But for some reason it only deciphers every second letter... I have no clue what to change or do. Thanks

function rot13(str) {
  let regexp = /\w/gi;
  let obj = {
    "A": "N",
    "B": "O",
    "C": "P",
    "D": "Q",
    "E": "R",
    "F": "S",
    "G": "T",
    "H": "U",
    "I": "V",
    "J": "W",
    "K": "X",
    "L": "Y",
    "M": "Z",
    "N": "A",
    "O": "B",
    "P": "C",
    "Q": "D",
    "R": "E",
    "S": "F",
    "T": "G",
    "U": "H",
    "V": "I",
    "W": "J",
    "X": "K",
    "Y": "L",
    "Y": "M",
  };
  for (let i = 0; i < str.length; i++) {
    if (regexp.test(str[i])) {
      str = str.replace(str[i], obj[str[i]]);  
    }
  };
  return str;
}
console.log(rot13("SERR"));

//output: FEER

//wanted output: FREE

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

究竟谁懂我的在乎 2025-01-26 02:28:27

您有两个问题:

  • 在将正则使用g标志时,正则是状态的,并且.test方法会跟踪其正在搜索的字符串中的位置。

exec()(或与之结合使用),test()在同一全局正则表达式实例上多次调用上一场比赛。

这意味着,当您使用全局标志时,一旦正则正则匹配一个字符,在重置一个角色之前,它将不匹配另一个字符:

const rgx = /\w/g;

console.log("Different results!:", rgx.test("a"), rgx.test("a"))

这是您看到的“其他所有字符”替换的原因,因为循环中的IF条件只会在其他所有通过时执行。

为了解决这个问题,除非您需要状态行为,否则只需避免在正则标志上使用g标志。

第二个问题:

  • .replace方法与字符串作为第一个参数时, 仅将替换该字符串的第一个实例。

这意味着如果您要替换字符出现在较早的情况下,将是较早的角色被交换,而不是当前索引上的字符。

console.log("Only the first is replaced!:", "aaaa".replace("a", "b"))

调整此调整的一种方法是,而不是使用.replace尝试交换字符,而是使用.slice重建字符串,同时更改其对应方的编码字符。此方法可确保更改的字符是您当前索引i的一个:

str = str.slice(0, i) + obj[str[i]] + str.slice(i+1)

将所有内容放在一起,您可以像这样修改片段:

function rot13(str) {
  let regexp = /\w/i; // No global match!
  let obj = {
    "A": "N",
    "B": "O",
    "C": "P",
    "D": "Q",
    "E": "R",
    "F": "S",
    "G": "T",
    "H": "U",
    "I": "V",
    "J": "W",
    "K": "X",
    "L": "Y",
    "M": "Z",
    "N": "A",
    "O": "B",
    "P": "C",
    "Q": "D",
    "R": "E",
    "S": "F",
    "T": "G",
    "U": "H",
    "V": "I",
    "W": "J",
    "X": "K",
    "Y": "L",
    "Z": "M",
  };
  for (let i = 0; i < str.length; i++) {
    if (regexp.test(str[i])) {
      str = str.slice(0, i) + obj[str[i]] + str.slice(i+1)
    }
  };
  return str;
}

console.log(rot13("SERR"));
//output: FREE

You have two issues:

  • When using the g flag on a regex, the regex becomes stateful, and the .test method keeps track of where in the string it is searching. From MDN:

As with exec() (or in combination with it), test() called multiple times on the same global regular expression instance will advance past the previous match.

This means that when you use the global flag, once the regex has matched one character, it will not match another until it has been reset:

const rgx = /\w/g;

console.log("Different results!:", rgx.test("a"), rgx.test("a"))

This is what is responsible for the "every other character" replacement that you see, since the if condition in your loop will only execute on every other pass.

To fix that, just avoid using the g flag on the regex unless you need stateful behavior.

Second issue:

  • When using the .replace method with a string as the first argument, only the first instance of that string will be replaced.

This means if the character you are replacing appears earlier, it will be that earlier character that is swapped, rather than the one at your current index.

console.log("Only the first is replaced!:", "aaaa".replace("a", "b"))

One way to adjust for that is instead of using .replace to try and swap the character, rebuild the string using .slice while changing out the encoded character for its counterpart. This method ensures the character that is changed is the one at your current index i:

str = str.slice(0, i) + obj[str[i]] + str.slice(i+1)

Putting that all together, you could modify your snippet like so:

function rot13(str) {
  let regexp = /\w/i; // No global match!
  let obj = {
    "A": "N",
    "B": "O",
    "C": "P",
    "D": "Q",
    "E": "R",
    "F": "S",
    "G": "T",
    "H": "U",
    "I": "V",
    "J": "W",
    "K": "X",
    "L": "Y",
    "M": "Z",
    "N": "A",
    "O": "B",
    "P": "C",
    "Q": "D",
    "R": "E",
    "S": "F",
    "T": "G",
    "U": "H",
    "V": "I",
    "W": "J",
    "X": "K",
    "Y": "L",
    "Z": "M",
  };
  for (let i = 0; i < str.length; i++) {
    if (regexp.test(str[i])) {
      str = str.slice(0, i) + obj[str[i]] + str.slice(i+1)
    }
  };
  return str;
}

console.log(rot13("SERR"));
//output: FREE

走过海棠暮 2025-01-26 02:28:27

这似乎很好

const rot13 = (str) => {
  const base = 'A'.charCodeAt()
  
  return str
  .split('')
  .map(c => String.fromCharCode(((c.charCodeAt() - base + 13) % 26) + base)).join('')


}

console.log(rot13('SERR'))

This seems to work fine

const rot13 = (str) => {
  const base = 'A'.charCodeAt()
  
  return str
  .split('')
  .map(c => String.fromCharCode(((c.charCodeAt() - base + 13) % 26) + base)).join('')


}

console.log(rot13('SERR'))

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文