/now
projects
ramblings
smol projects

mubashir cipher

13.11.2023 2 min read

In Mubashir Cipher, encoding is done by simply replacing paired letters from the provided key.

Create a function that takes a string containing the message to be encoded with a fixed given 2D array of letters key.

There are some variations on the rules of encipherment. One version of the cipher rules are outlined below:

key = [['m', 'c'], ['u', 'e'], ['b', 'g'], ['a', 'k'],
    ['s', 'v'], ['h', 'x'], ['i', 'z'], ['r', 'y'],
    ['p', 'w'], ['l', 'n'], ['o', 'j'], ['t', 'f'], ['q', 'd']]
mubashirCipher("mubashir is not amazing") ➞ "cegkvxzy zv ljf kckizlb"
mubashirCipher("%$ &%") ➞ "%$ &%"
mubashirCipher("evgeny sh is amazing") ➞ "usbulr vx zv kckizlb"

Note: we have to index both ways, i.e. the mapping has to be bi-directional. If we get “m”, we’ll need to replace it with “c”. If we get “c”, we need to replace it with “m”.

Note: I omit the key array for brevity.

crystal:

def mubashir_cipher_hash(msg : String)
  h = Hash(Char, Char).new
  KEY.each { |a|
    h[a[0]] = a[1]
    h[a[1]] = a[0]
  }
  msg.chars.map { |ch| h.has_key?(ch) ? h[ch] : ch }.join
end

A pitfall I constantly fall into: trying to treat characters the same way as strings. Here, we have to use .chars instead of .split because .split gives us an array of strings, and our KEY array holds Chars.

Moving to nim:

proc mubashirCipher(s: string): string =
    var h = newOrderedTable[char, char]()
    for arr in key:
        h[arr[0]] = arr[1]
        h[arr[1]] = arr[0]
    s.toSeq.map(proc(ch: char): char =
        if h.hasKey(ch): h[ch]
        else: ch
    ).join

raku:

sub mubashir-cipher-hash($s) {
    my %h = %{};
    for @key -> ($a, $b) { 
        %h{$a} = $b;
        %h{$b} = $a;
    };
    $s.comb.map({ %h{$_}:exists ?? %h{$_} !! $_ }).join;
}

ts/js:

function mubashirCipher(s: string) {
  const entries = key.reduce((acc, currVal) => {
    return { ...acc, [currVal[0]]: currVal[1], [currVal[1]]: currVal[0] };
  }, {});

  return s
    .split("")
    .map((el) => (entries[el] ? entries[el] : el))
    .join("");
}

Overall, this kata took longer than expected, but maybe it’s because I’m not feeling too well… That said, I should probably go and take a break now.

Built with Astro and Tailwind 🚀