Obfuscate javascript properties?

妖精的绣舞 提交于 2019-12-09 12:30:13

问题


I've recently tested UglifyJS and YUI Compressor and noticed something odd.
Both minifiers don't seem to change the names of object properties, only the names of variables and functions.

for instance if I have the following code:

var objName = {first:2, second:4};
alert(objName.first + " " + objName.second);

the names first and second remain unchanged in the minified version.
Why is that?


回答1:


It's because it doesn't know where the object is going to be used. It could be used externally by other code and you wouldn't want your other code to have to change whenever you obfuscate it.

Edit So basically, it's like that to prevent obfuscation from breaking external/internal references to properties that may not be possible to figure out while obfuscating.




回答2:


Since in javascript a new scope is created in a function, you can scope your code in an immediately invoked function.

   // scoped
(function() {
    var objName = {first:2, second:4};
    alert(objName.first + " " + objName.second);
})();

Then using Google's Closure Compiler, if you turn on the "Advanced" optimization it will see that the properties are only used locally, and will obfuscate them.

   // result
var a={a:2,b:4};alert(a.a+" "+a.b);



回答3:


Since there are no well defined scoping rules around objects in JavaScript it's impossible to obfuscate the names in a way that is guaranteed to be correct.

For example, if you had the following function:

function f() {
   return { first: 'foo', second: 'bar' };
}

In order to obfuscate the property names you would have to nail down all the places that f is called from. Since functions are first-class in JavaScript they can be assigned and passed around in arbitrary ways making it impossible to pin down where f is referenced without actually running the program.

Additionally, JavaScript doesn't have any way for you to specify intent around what's public API and what isn't. Even if the minimizer could reliably determine where the function is called from in the code you give it, there would be no way for it to make the same changes to code that it hasn't seen.




回答4:


I guess that's because the minifiers would break the object properties. Consider this:

function getProp(ob,name) {
   return ob[name];
}

var objName = {first: 2, second: 4};
var prop = getProp(objName, "second");

There's no way for the minifier to know the string literal "second" being an object property. The minified code could look like this then:

function a(b,c){return b[c]}var d={p1:2,p2:4};var e=a(d,"second")

Broken now.




回答5:


The latest release of uglify (today) has object property mangling, see v2.4.19. It also supports reserved files for excluding both object properties and variables that you don't want mangled. Check it out.




回答6:


The only public tool so far to obfuscate property and function names (afaik) is the Closure Compiler's Advanced mode. There are a lot of limitations and restrictions, but the end result is generally worth it.

As a passing note: the Dojo Toolkit is compatible (with some minor modifications) with the Closure Compiler in Advanced mode -- arguably the only large-scale public JavaScript library that can be fully obfuscated. So if you are looking at obfuscation to protect your IP, you should look into using Dojo for the task.

http://dojo-toolkit.33424.n3.nabble.com/file/n2636749/Using_the_Dojo_Toolkit_with_the_Closure_Compiler.pdf?by-user=t

  • Stephen



回答7:


What about doing something like:

// scoped
(function() {
var objName = {first:2, second:4};
var vA = 'first';
var vB = 'second';

alert(objName[vA] + " " + objName[vB]);
})();

Once objName.first and/or objName.second are referenced enough times, this technique will start to save characters. I can't think of any reason that wouldn't work, but I can't find any minifiers that do it.



来源:https://stackoverflow.com/questions/5081293/obfuscate-javascript-properties

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!