Skip to content

Instantly share code, notes, and snippets.

@lewdev
Last active May 17, 2024 02:01
Show Gist options
  • Save lewdev/ca3ad1c3f7584c9a4d7078268309e84b to your computer and use it in GitHub Desktop.
Save lewdev/ca3ad1c3f7584c9a4d7078268309e84b to your computer and use it in GitHub Desktop.
πŸ”‹ JEX - a Base 72 encoding using URL safe characters

πŸ”‹ JEX - a Base 72 encoding using URL safe characters

I was thinking about storing data in the URL which is probably not a unique idea, but I wanted to see how to implement it myself.

Compression can also be achived by combining two values to indicate repeating values. i.e. 55 = 5,5,5,5,5

Also storing data in URLs, but with a bigger range by converting text to Hex-like values using its character code.

A single character can be a number up to 73 and therefore, two characters can store numbers up to 5329.

URL unsafe charactrers

I looked up characters that need to encoded starting with the % so that we don't use more data to represent more values.

&$+,/:;=? @#<>[]{}|\^%`

Compression for litecanvas paint

A great usecase is this where we would likely have a lot of repeating values are images:

litecanvas Pixel Art Editor (source)

Maybe I can apply this to his game engine.

URL safe characters

When it comes to ANSI characters, these are considered safe for the URL.

0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz!-."'()*`~

TODO

  • Number to "hex" code (i.e. 63 is 0z)
  • Compression using these characters (i.e. "5Z" is 5 repeated 36 times)

This is useful for storing images or grid values with up to 73 colors or consecutive pixels/cells.

String to Char Codes to JEX

Sorry if you hate this name, but I'm calling this Jexidecimal (jex for short) which is a format for storing URL-safe values. I'm still working it out, but I think jex is a good short name to convert values a URL.

<input onkeyup="o.innerHTML = jexStr(this.value)">
<p id=o></p>
<script>
const S = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz!-.\"'()*`"; //~ is saved for something

const L = S.length;
const jexStr = s => [...s].map(c => jex(c.charCodeAt())).join` `;
const jex = n => {
  const s = [];
  let q = n;
  while(true) {
    if (n >= L) {
      s.unshift(S[n % L]);
      n = ~~(n / L);
    }
    else {
      s.unshift(S[n]);
      return s.join``;
    }
  }
  return s.join``;
};
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment