如何在 electron nodejs 中创建自定义字母字符映射

How to create a custom alphabet charatcer map in electron nodejs

一位客户要求我编写一个桌面应用程序,使用户能够为消息创建自定义字符映射表。为了更清楚,考虑消息 Hello! 它可以变成 Atco! 因为用户已经决定为每个字母分配一个不同的字母,在示例中 H 字母被 A 等。将阅读收到的消息的用户将知道决定的字符映射,并将能够将消息解码回 Hello!

目前我已经开始编写 UI 代码,但我不知道什么 javascript 函数可以帮助我实现这一点。我正在考虑使用一个数组来保存所有字母,并让用户从中创建他的自定义字符映射。

// original char map
const charMap = ['a','b','c', ...];

// char map decided by the user taken from input?
const customCharMap = { a: f, b: h, c: n };

我有两个关于如何进行的问题:

  1. 让用户设置自定义字符映射的最好最快的方法是什么?我正在考虑为每个字母使用 <select> 输入类型,但我不确定这一点,因为我认为用户手动设置每个字母可能会很烦人。您建议如何为这项任务提供良好的用户体验?

  2. 如果我想以随机方式创建自定义字符映射而不让用户能够设置每个字母但只能看到生成的字符映射,javascript?我如何将生成的随机字符映射发送给接收者以便他可以解码消息?

更新

我正在测试此代码以生成随机字符映射。问题是输出会有重复的字母分配,这不是我所期待的


const customCharMap = () => {
    const originalCharMap = ['a','b','c','d','e','f','g','h','i','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];
    let outputCharMap = {};
    for(let i = 0; i < originalCharMap.length; i++){
        let rnd = Math.floor(Math.random() * originalCharMap.length);
        outputCharMap[originalCharMap[i]] = originalCharMap[rnd];
    }
    return outputCharMap;
}

const result = customCharMap();

console.log(result);


//output
{
  a: 'd',
  b: 'd',
  c: 'd',
  d: 'f',
  e: 'o',
  f: 'p',
  g: 'q',
  h: 'a',
  i: 'o',
  l: 'x',
  m: 'm',
  n: 'r',
  o: 'i',
  p: 'i',
  q: 'e',
  r: 'e',
  s: 't',
  t: 'u',
  u: 'p',
  v: 'g',
  w: 'l',
  x: 'u',
  y: 'y',
  z: 'r'
}

创建随机字符映射的一种方法可以是:

  1. 创建一个代表字母表的数组
  2. 使用 Fisher-Yates algorithm as described in this article
  3. 创建数组的随机副本
  4. 使用这两个数组来创建你的人物地图

// 1. create an array representing the alphabet
const alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']

// 2. create a shuffled copy of the array using the Fisher-Yates algorithm
function shuffleArray(arr) {
  const output = [...arr]
  for (let i = output.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    const temp = output[i];
    output[i] = output[j];
    output[j] = temp;
  }
  return output
}

const shuffled = shuffleArray(alphabet);

// 3. use the two arrays to create the characters map
const charMap = alphabet.reduce((outObj, item, index) => {
  outObj[item] = shuffled[index];
  outObj[item.toUpperCase()] = shuffled[index].toUpperCase(); // if you want to map capital letters too
  return outObj;
}, {});

console.log(charMap);

[编辑] 但是,现在我想起来了,你可能不需要一个对象作为字符映射;您可以简单地使用 shuffled.join('') 生成的字符串作为 encrypt/decrypt 消息的键。 它可能需要您为加密和解密消息的函数编写更多代码,但从好的方面来说,如果密钥已经是一个字符串而不是一个对象,您将不必将其字符串化以通过网络发送它,并且再次将其解析到目的地。