Vue

by khamer

HTML

<main>
  <textarea v-model="message"></textarea>
  <br>
  :{{ invisible }})
  <hr>
  
  <textarea v-model="encMessage"></textarea>
  <br>
  {{ decoded }}
</main>

CSS

textarea {
  display: block;
  width: 100%;
  height: 6rem;
}

main {
  padding: 1rem;
  font-family: arial;
}

Vue

enc = new TextEncoder();
dec = new TextDecoder();

new Vue({
  el: "main",
  data: {
    message: '',
    filler: '',
    encMessage: '',
  },
  computed: {
    asBinary() {
      let v = enc.encode(this.message);
      let r = [];
      for (let i = 0; i < v.length; i++) {
        r[i] = v[i].toString(2).padStart(8, 0);
      };

      return r.join('');
    },

    invisible() {
      return this.asBinary.replace(/0/g, '‌')
        .replace(/1/g, '​');
    },

    bin() {
      let b = this.encMessage
        .replace(/[^​‌]/g, '')
        .replace(/​/g, '1')
        .replace(/‌/g, '0')
        .match(/[01]{8}/g);
        
      return b || [];
    },

    decoded() {
    return dec.decode(new Uint8Array(
    this.bin.map(v => parseInt(v, 2))
    ));
  }
}
        })