JavaScript number obfuscater I got inspired to do this after seeing this repo containing a bunch of weird syntactical quirks in JS, namely this example called "It's a fail!". The example was essentially the following:


  You would not believe, but …

(![] + [])[+[]] +
 (![] + [])[+!+[]] +
 ([![]] + [][[]])[+!+[] + [+[]]] +
 (![] + [])[!+[] + !+[]];
// -&gt; 'fail'



I found this quite interesting; however, as revealed by the explanation later on, the actual characters were merely coincidentally obtained using the fact that certain array operations return true, false and undefined, from which we can grab certain indices. The issue with using this for text obfuscation, of course, it that it's not applicable to most characters. However, the way we grab those indices is also using some array syntax, following just three rules:

// Number definitions
+[] // -&gt; 0
+!+[] // -&gt; 1

// Addition
+!+[] + +!+[] // -&gt; 2
+!+[] + !+[] // -&gt; also 2, but with one less character

// Concatenation by arrayifying
+!+[] + [+[]] // -&gt; 10
+!+[] + [+!+[]] // -&gt; 11


Using this, we could implement an algorithm to convert any number into such a format. I've also made some optimisations, so for example, instead of doing +!+[] + +!+[] + +!+[] + +!+[] + +!+[] + +!+[] + +!+[] + +!+[] just to do 9, we could simply do [+!+[] + [+[]] - !+[]] - making 10 by concatenating 1 and 0, then subtracting 1. The same process is done for any number > 5.

Below is my code. Any comments on readability, naming, etc. is obviously welcome, but I'm also open to any suggestions on further ways to make the output number more compact.

const obfuscateNumber = num =&gt; {
  let chars = [...num.toString()];

  let outputStr = "";
  let tokens = 0;
  chars.forEach(char =&gt; {
    let digit = parseInt(char);

    outputStr += (tokens &gt; 0? " + " : "")
    if (digit === 0){
      outputStr += (tokens &gt; 0? "[" : "") 
                      + "+[]" 
                      + (tokens &gt; 0? "]" : "");
    } else if (digit === 1) {
      outputStr += (tokens &gt; 0? "[" : "") 
                      + "+!+[]" 
                      + (tokens &gt; 0? "]" : "");
    } else if (digit &lt;= 5) {
      outputStr += "[";
      for (i = 0; i &lt; digit; i++){
        outputStr += (i == 0? "" : " + ") + "!+[]";
      }
      outputStr += "]";
    } else {
      outputStr += "[+!+[] + [+[]]";
      for (i = 0; i &lt; 10 - digit; i++){
        outputStr += " - !+[]";
      }
      outputStr += "]";
    }

    tokens++;
  });

  return outputStr;
}


Note: when I use the word 'obfuscate', I mean it in the sense that the number is unreadable to average humans. Obviously, it easily decodable, and I'm not planning to implement it into some production-grade obfuscation software therefore.
Your custom function is 36 lines of very hard to digest code.  You are performing a battery of if-elseif-else conditionals on the same variable -- for this reason, it is most appropriate to employ a switch case (even though I have a strong bias against them) as a matter of best practice.  If the goal is to obfuscate the output AND the code, I reckon you've found a winner.



I'll offer a comparison using tests 5, 11, and 987654321.

Test Results:

5 -&gt; [!+[] + !+[] + !+[] + !+[] + !+[]]
11 -&gt; +!+[] + [+!+[]]
987654321 -&gt; [+!+[] + [+[]] - !+[]] + [+!+[] + [+[]] - !+[] - !+[]] + [+!+[] + [+[]] - !+[] - !+[] - !+[]] + [+!+[] + [+[]] - !+[] - !+[] - !+[] - !+[]] + [!+[] + !+[] + !+[] + !+[] + !+[]] + [!+[] + !+[] + !+[] + !+[]] + [!+[] + !+[] + !+[]] + [!+[] + !+[]] + [+!+[]]


Alternatively, you might leverage Javascript-native calls to base64 encode: btoa() and atob().  Because you are dealing purely with integers, you don't need to concern yourself with "The Unicode Problem".
To encode a number use btoa(num) and to decode it back use atob(num).

Test Results:

5 -&gt; NQ==
11 -&gt; MTE=
987654321 -&gt; OTg3NjU0MzIx


Benefits include:


Future developers of your code will be able to instantly research what your process is doing.
There is no need to write a custom function
The output is far, far better compressed
The process of decrypting the generated string is just as simple as encrypting it
If you want to further obfuscate the generated strings, you can cleanly add your own "special sauce" that will offer more "entertainment" for crackers.