Good way to obfuscate Javascript code in Gulp [duplicate] - javascript

This question already has answers here:
How can I obfuscate (protect) JavaScript? [closed]
(22 answers)
Closed 3 years ago.
This question knowing that obfuscation is by no means a strong way to protect code...
Using Gulp, I'm looking for a way to prevent my app's content to appear in a too obvious manner. Not manipulating sensitive data, but I'd still not want my minified code to look too obvious to modify.
Been trying gulp-minify and gulp-uglify, but either my use of them is wrong, either they don't fill my need.
Needs being:
- function renaming
- variable renaming
- string obfuscation (at least prevent the string from being human readable at first glance)
- not more than 2x the storage needs
What would be the suggested approaches, leads, plugins?
Thanks in advance,

Just try this: Javascript Obfuscator.
As far as I know, it's almost impossible to revert the obfuscated code back to the original.

So far, the most effective (in my case) is to pipe the following code, which just applies character rotation:
function obfuscate(text, 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 text.toString();
}
var chars = text.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('');
},
function defuse(text, 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 text.toString();
}
return obfuscate(text.toString(), n - key);
}

You may want to consider gulp-javascript-obfuscator. It's a node module and version ^1.1.5 worked very well for me. It also has the option to minify with the following code:
// Imports ...
obfuscator = require('gulp-javascript-obfuscator')
// ... Other code
gulp.src('my_file.js')
.pipe(obfuscator({compact:true}))
.pipe(gulp.dest('dist'));

Related

Javascript - Find opening and closing bracket positions on a string?

I'm making a calculator for a site project of mine where you can type your entire expression before resolving, for example: 2+3*4 would return 14, 22-4 would return 18, 20+5! would return 140, and so on.
And that works for simple expressions like the ones I showed, but when I add brackets the code breaks.
So a simple expression like (2+3)! that should return 120 actually returns 10 or 2+3!.
my original ideia to make even the basic 2+3! work was to separate the string in math simbols and the rest. so it would separate in this case it would separate it into 2, + and 3!; where it would find the symbol and resolve just that part. And that's why it solves 10 instead of not working.
But after trying to solve I couldn't make the code work except in a extremely specific situation, so I decided to redo the code and post this here in case someone could help me out.
This is the function that I'm currently using to prepare my string for evaluation:
function sepOperFat(){
//2+3! it's working
//1+(2-(2+2)+3)! want that to work in the end
var value = document.calculator.ans.value;
var operandoPos = ['0'];
var operandoInPos = [''];
var paraResolver = [];
for(i = 0; i <= value.length; i++){
//check if value[i] is equal to +, -, ×, ÷, * & /
if(value[i] == '+' || value[i] == '-' || value[i] == '×' || value[i] == '÷' || value[i] == '*' || value[i] == '/'){
operandoPos.push(i);
operandoInPos.push(value[i]);
}
}
paraResolver.push(value.slice(operandoPos[0], operandoPos[1]));
for(var total = 1; total <= operandoPos.length; total++){
paraResolver.push(value.slice(operandoPos[total] + 1, operandoPos[total + 1]));
}
document.calculator.ans.value = '';
for(var total = 0; total <= paraResolver.length - 2; total++){
if(paraResolver[total].includes('!')){
document.calculator.ans.value += "factorial(" + paraResolver[total] + ")";
}else{
document.calculator.ans.value += paraResolver[total];
}
document.calculator.ans.value += operandoInPos[total + 1];
}
}
document.calculator.ans.value is the name of the string where i have the expression.
operandoPos is the position on the string where a symbol is at.
operandoInPos is the symbol (I maybe could have used value.charAt(operandoPos) for that too).
paraResolver is the number that I will be solving (like 3).
factorial( is the name of my function responsible for making the number factorial.
the function doesn't have a return because I still want to solve inside the document.calculator.ans.value.
to resolve the equation I'm using document.calculator.ans.value = Function('"use strict"; return '+ document.calculator.ans.value)(); that activates when I press a button.
And yeah, that's it. I just want a function capable of knowing the difference between (2+3)! and 2+(3)! so it can return factorial(2+3) instead of (2+factorial(3)).
Thank you for your help.
Your biggest problem is going to be that order of operations says parentheses need to be evaluated first. This might mean your code has to change considerably to support whatever comes out of your parentheses parsing.
I don't think you want all of that handled for you, but an approach you can take to sorting out the parenthesis part is something like this:
function parseParentheses(input) {
let openParenCount = 0;
let myOpenParenIndex = 0;
let myEndParenIndex = 0;
const result = [];
for (let i = 0; i < input.length; i++) {
if (input[i] === '(') {
if (openParenCount === 0) {
myOpenParenIndex=i;
// checking if anything exists before this set of parentheses
if (i !== myEndParenIndex) {
result.push(input.substring(myEndParenIndex, i));
}
}
openParenCount++;
}
if (input[i] === ')') {
openParenCount--;
if (openParenCount === 0) {
myEndParenIndex=i+1;
// recurse the contents of the parentheses to search for nested ones
result.push(parseParentheses(input.substring(myOpenParenIndex+1, i)));
}
}
}
// capture anything after the last parentheses
if (input.length > myEndParenIndex) {
result.push(input.substring(myEndParenIndex, input.length));
}
return result;
}
// tests
console.log(JSON.stringify(parseParentheses('1!+20'))) // ["1!+20"]
console.log(JSON.stringify(parseParentheses('1-(2+2)!'))) // ["1-",["2+2"],"!"]
console.log(JSON.stringify(parseParentheses('(1-3)*(2+5)'))) // [["1-3"],"*",["2+5"]]
console.log(JSON.stringify(parseParentheses('1+(2-(3+4))'))) // ["1+",["2-",["3+4"]]]
this will wrap your input in an array, and essentially group anything wrapped in brackets into nested arrays.
I can further explain what's happening here, but you're not likely to want this specific code so much as the general idea of how you might approach unwrapping parenthesis.
It's worth noting, the code I've provided is barely functional and has no error handling, and will behave poorly if something like 1 - (2 + 3 or 1 - )2+3( is provided.

Setting multiple javascript variables at once [duplicate]

This question already has answers here:
What does a comma do in assignment statements in JavaScript?
(4 answers)
Closed 4 years ago.
I found some code which looks like this
var v = color.val(), sel_c = (v == '') ? "#234872" : v;
I'm not sure why it was written like this, but I was wondering how to read it. If we'd just have
var v = color.val();
or
var sel_c = (v == '') ? "#234872" : v;
I'd understand. But what does it mean when you separate it with commas? Its as if we were trying to set multiple variables at once or something...
The comma operator is used to separate multiple statements.
In the case of variable assignment it is just a way to leave out subsequent var keywords. Each variable is set in turn
Yap, totally valid to omit having to write var, let or const multiple times
const a = 1,
b = a + 1,
c = b + 1;
console.log(a, b, c);
Is the same as
const a = 1;
const b = a + 1;
const c = b + 1;
just a few var, let or const fewer to write.
The following is the equivalent of the code you posted:
var v= color.val();
var sel_c;
if(v==''){
sel_c="#234872"
}else{
sel_c=v;
}
As for why it was written as you posted it - I believe it is to conserve "space". And by space I dont mean bytes of data, but rather lines in the code editor. At least that is the reason I always get. I personally think that written like that the code is less readable, even if more compact.
This:
var v = color.val(), sel_c = (v == '') ? "#234872" : v;
equals to:
var v = color.val();
var sel_c = (v == '') ? "#234872" : v;
The only benefit of writing it on one line is that your code will be a bit "shorter".
I personally find it ugly and hard to read.

How to write a script that will calculate an interest rate

I am building a form using the WP plugin called Calculated Fields Form.
The first question is for people to enter the amount they want to invest (fieldname2)
The second question is for people to select the number of months (fieldname3)
Based on the amount and the length, a different interest rate should be displayed.
I am supposed to enter the equation myself so I wrote the following script to try but it doesn't work.
(function()`{`
if (50<=fieldname2<=99 && fieldname3=3) return fieldname2*4/100;
if (50<=fieldname2<=99 && fieldname3=6) return fieldname2*6/100;
if (50<=fieldname2<=99 && fieldname3=12) return fieldname2*8/100;
`}`)();
It's a little unclear what you are trying to achieve here but the issues with your code are as follows:
(function()`{`
// --------^^^ unexpected template string
if (50<=fieldname2<=99 && fieldname3=3) return fieldname2*4/100;
// ------^^^ this is not valid ----^^^ should be === not =
if (50<=fieldname2<=99 && fieldname3=6) return fieldname2*6/100;
if (50<=fieldname2<=99 && fieldname3=12) return fieldname2*8/100;
`}`)();
// immediately invoked function - but why?
// what happens if "50<=fieldname2<=99" is not satisfied?
A bit of advice - write the function first as a testable entity to see if it is even getting the result you want. Use expressive arguments so you can reason about what you are doing. Consider cases that are not covered by your function (see comments below). In those cases, you will return undefined which I doubt is desirable.
function calculateInterest (amount, months) {
if (50 <= amount && amount <= 99) {
if (months === 3) return amount*4/100;
if (months === 6) return amount*6/100;
if (months === 12) return amount*8/100;
// what should we return if months does not satisfy one of the above?
}
// what should we return if amount does not satisfy the above?
}
Assuming fieldname2 and fieldname3 are variables that exist in your code, you can now call the function calculateInterest(fieldname2, fieldname3)

Recursive Longest Common Subsequence looping or taking forever?

I am developing a JavaScript application and I needed a recursive algorithm for the longest common subsequence, so I went here and tried this one out.
It goes like this:
function lcs(a, b) {
var aSub = a.substr(0, a.length - 1);
var bSub = b.substr(0, b.length - 1);
if (a.length === 0 || b.length === 0) {
return '';
} else if (a.charAt(a.length - 1) === b.charAt(b.length - 1)) {
return lcs(aSub, bSub) + a.charAt(a.length - 1);
} else {
var x = lcs(a, bSub);
var y = lcs(aSub, b);
return (x.length > y.length) ? x : y;
}
}
It worked fine with the few test cases i tried until now, but I found that it loops on the following test case:
a: This entity works ok
b: This didn't work ok but should after
It also loops with:
a: This entity works ok
b: This didn't work as well
which at some point should get in the middle branch.
I have noticed that it is a translation of a Java version (here) of the same algorithm. It goes like this:
public static String lcs(String a, String b){
int aLen = a.length();
int bLen = b.length();
if(aLen == 0 || bLen == 0){
return "";
}else if(a.charAt(aLen-1) == b.charAt(bLen-1)){
return lcs(a.substring(0,aLen-1),b.substring(0,bLen-1))
+ a.charAt(aLen-1);
}else{
String x = lcs(a, b.substring(0,bLen-1));
String y = lcs(a.substring(0,aLen-1), b);
return (x.length() > y.length()) ? x : y;
}
}
I supposed that the JavaScript translation was wrong assuming that String.substr() and String.substring() were the same (which they aren't).
To be sure that it wasn't the case, I tried the Java one on the same test case here.
Guess what? Also the java version does not end.
I am struggling to debug it, as it is recursive.
Anyone has any idea on what is going wrong with it?
As others have pointed out in the comments, the program itself is correct. The issue you are experiencing is due that, in this implementation, the code has an exponential time complexity, and therefore takes A LONG time to run with your example input. If you let it run for a LONG time, it will return the correct result.
As others have also pointed out in the comments, LCS between two Strings is solvable with a lower time complexity using dynamic programming, which will solve it much quicker. Refer to the internet for more help (wikipedia ) or, better, try to solve it yourself thinking about the fact that there are, for each String of length n, exactly N^2 substrings. You can trivially solve it in N^2*M^2 (n m are the lengths of the two strings) by just checking if any substring of a is present in b. Ask yourself if you can do better for exercise? If yes how, if no, why.

Javascript (-1 <= 5 <= 1) === true?

I want to validate that a given number is within a given range:
function validate(min, max, amount) {
return (min <= amount <= max);
}
But this does not seem to work properly. I know I can do it with two comparison and a logical AND, but I would like to it in one comparison. Is there any NATIVE javascript way to realize this?
Use this instead :
return (min <= amount && amount <= max);
There is no shortcut. And there is a good reason the JavaScript engine can't guess your intent : what you typed was valid, it just isn't interpreted as you'd like. You were testing, in fact
((min <= amount) <= max)
and the result of the first comparison, which is a boolean, is converted to 0 or 1 for the second one (more details here about operators precedence, those comparison operators are left-to-right).
If you really want a shortcut, you could do this :
Number.prototype.isin = function(m,M) {
return m<=this && this<=M;
};
console.log(0.5.isin(1,2)); // logs false
console.log(3..isin(2,5)); // logs true
but I personally would use the standard solution with && that everybody can read and which doesn't involve an additional function call.
Aside : I could have called my function in instead of isin but it might break ES3 browsers.
Operators ( == , <= , < , >= , == ) take only 2 arguments.
When there are more arguments it uses mathematical order of computing. So in fact your code behave like:
min <= amount // true
true <= max // this is illogical
It's also optimal, because when executing logical statements and finding something like:
if(false && (some computing))
It will ignore (some computing) because result will be always false
This is very common practive in every language. Test like this will not have NullPointerException error, because first argument is already false.
if(obj != null && obj.getValue() > 10) //C++,Java, etc.
if(obj !== undefined && obj.val() > 10) // javascript
if(obj.length != 0 && obj.val() > 10) //jQuery

Categories