Simplest way to obfuscate and deobfuscate a string in JavaScript
Solution 1
You can use btoa() and atob(). btoa()
is like base64_encode()
and atob()
like base64_decode()
.
Here is an example:
btoa('Some text'); // U29tZSB0ZXh0
atob('U29tZSB0ZXh0'); // Some text
Keep in mind that this is not a secure way to keep secrets. Base64 is a binary-to-text encoding scheme that represents binary data in an ASCII string format by translating it into a radix-64 representation.
Solution 2
It's worth noting that
(![]+[])[+[]]+(![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]
evaluates to the string "fail" without ever looking like a string. Seriously, enter it into node and be amazed. You can spell anything in JavaScript by being crazy.
Solution 3
I'm obviously too late for an answer, but I was just working on another solution for the problem and base64 seemed to be to weak.
It works like this:
"abc;123!".obfs(13) // => "nopH>?@."
"nopH>?@.".defs(13) // => "abc;123!"
Code:
/**
* Obfuscate a plaintext string with a simple rotation algorithm similar to
* the rot13 cipher.
* @param {[type]} key rotation index between 0 and n
* @param {Number} n maximum char that will be affected by the algorithm
* @return {[type]} obfuscated string
*/
String.prototype.obfs = function(key, n = 126) {
// return String itself if the given parameters are invalid
if (!(typeof(key) === 'number' && key % 1 === 0)
|| !(typeof(key) === 'number' && key % 1 === 0)) {
return this.toString();
}
var chars = this.toString().split('');
for (var i = 0; i < chars.length; i++) {
var c = chars[i].charCodeAt(0);
if (c <= n) {
chars[i] = String.fromCharCode((chars[i].charCodeAt(0) + key) % n);
}
}
return chars.join('');
};
/**
* De-obfuscate an obfuscated string with the method above.
* @param {[type]} key rotation index between 0 and n
* @param {Number} n same number that was used for obfuscation
* @return {[type]} plaintext string
*/
String.prototype.defs = function(key, n = 126) {
// return String itself if the given parameters are invalid
if (!(typeof(key) === 'number' && key % 1 === 0)
|| !(typeof(key) === 'number' && key % 1 === 0)) {
return this.toString();
}
return this.toString().obfs(n - key);
};
Rich Jenks
Updated on July 09, 2022Comments
-
Rich Jenks almost 2 years
I'm looking for a way to obfuscate and deobfuscate a string in JavaScript; by which I mean encryption and decryption when security is not an issue. Ideally something native to JS (like
base64_encode()
andbase64_decode()
in PHP) to "turn a string into something else and back again" without having to write a function.Any suggestions welcome!
-
Rich Jenks over 11 yearsSeems to work in most modern browsers so suits my requirements perfectly. Thank you!
-
UpTheCreek almost 11 yearsWorth noting that the encoded string will be larger than the non-encoded one.
-
Gant Laborde over 6 yearsgo into node and break it into its parts. It starts to make some morbid sense.
-
RedSparr0w over 6 yearsInteresting! got it working with most letters! jsfiddle.net/pg07yf87/2 Edit: this site also does it for you jsfuck.com
-
Aniket Suryavanshi over 6 yearsCross browser support seems good now. caniuse.com/#search=btoa It's safe to use.
-
ethancrist about 6 yearsThank you. I love the use-cases for this.
-
Patrick Roberts about 6 yearsThis code breaks
for...in
enumeration of strings, don't use this in production. -
Gan Quan over 4 years@PatrickRoberts
for ... in
should always bundle with.hasOwnProperty()
. You can also defineobfs
anddefs
without modifyingString.prototype
-
Patrick Roberts over 4 years@GanQuan that was my point. The answer shouldn't be polluting builtin prototypes at all. The
.hasOwnProperty()
"good practice" (/s) came about due to the frequency of polluting builtins, not because it's actually made necessary by the language design itself. Because of how common it is for libraries to pollute builtins with arbitrary extensions like this, I thinkfor...in
has unfortunately become rarely, if ever, the appropriate choice for enumeration of anything, strings included. -
Etienne Martin about 4 yearsYou have a nice little obfuscator but then it's exposed globally for anyone to see on the String prototype. Kinda beats the purpose.
-
Yetanotherjosh about 3 yearsIt is very important to note this will fail on strings containing unicode characters that do not belong to the 0-127 range of the ASCII character set, and therefore this function is insufficient for use on user input from almost any modern web app where people might use non-ascii chars. The MDN docs discuss how to deal with this, you must first convert the unicode characters to a byte string.
-
Robby Hoover over 2 yearsId like to add for anyone looking in the future, btoa and atob are deprecated and are only kept around for legacy web APIs, converting between base 64 encoded strings and binary data should be performed using Buffer.from(str, 'base64') and buf.toString('base64')