Skip to content

How to create a custom alphabet charatcer map in electron nodejs

A client asked me to write a desktop application that give the ability for the users of creating a custom char map for messages. To be more clear, consider the message Hello! it can become Atco! because the user have decided to asign to each letter a different one, in the example the H letter is replaced by the A etc. The user that will read thereceived message will know the decided charatcer map and will be able to decode the message back to Hello!.

At the moment I’ve started writing the UI code but I have no idea of what javascript function can help me to achive this. I’m thinking to use an array that will hold all the alphabet letters and from it let the user create his custom char map.

// 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 };

I have two question about how to proceed:

  1. What’s the best and quickest way to let the user set the custom char map? I’m thinking to use a <select> input type for each letter, but I’m not sure of this because I think that it can be annoing for the user to set manually each single letter. What do you suggest to do to have a good UX for this task?

  2. If I want to create the custom char map in a random way without give to the user the ability to set each letter but only to see the generated char map, what is the best option in javascript? How I will send to the receiver the generated random char map so he can decode the message?

UPDATE

I’m testing this code to generate a random char map. The problem is that the output will have duplicate letters assiged and this isn’t really what I was expecting

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'
}

Answer

One way to create a randomized characters map could be:

  1. create an array representing the alphabet
  2. create a shuffled copy of the array using the Fisher-Yates algorithm as described in this article
  3. use the two arrays to create your characters map

// 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);

[EDIT] But, now that I think about it, you might not need an object as character map; you could simply use the string generated by shuffled.join('') as key to encrypt/decrypt the message. It might require you to write a bit more code for the functions encrypting and decrypting the message but, on the plus side, if the key is already a string rather than an object you will not have to stringify it for sending it over the network and to parse it again to at destination.