JScrewIt
JScrewIt copied to clipboard
Shorter general code generator?
[All Supported Env.] '!!!!!' 26486 unescape(unescape("false2521false2521false2521false2521false2521".split(false).join("%"))) 22547 unescape("false21false21false21false21false21".split(false).join("%")) 17058, but with 'b' or 'c' escaped that'd be too long
(though I don't know what code generated by the present way
OK after I remove the () I get the '!!!!!' is turned into String.fromCharCode(33,33,33,33,33)
For larger code it may be a better solution to make a bootstrap(a function that modify self's attrib and return itself so can be called with a list of (xxx), with 10 xxx shorter than 6 EMPTY, [], +[], ![], [[]], !![], +!![], [![]], [+[]], []+[], have 100>127-32 and encode the rest chars. I wonder if String.fromCharCode have its space
Testrecord: [].filter.constructor(unescape("alertfalse28false27false48ellofalse2cfalse20false57false6frldfalse21false27false29".split(false).join("%")))() 19617 alert('Hello, World!') 28779 even if use "eval(...)" it would be shorter
';;;' 25961 unescape('%3B%3B%3B') 25867 unescape(unescape('false3false42false3false42false3false42'.split(false).join('%'))) 22115 unescape('false3Bfalse3Bfalse3B'.split(false).join('%')) 21048 unescape(3201714281..toString(15).split(1).join('%')) 20144, but require short source 'falsefalsefalse'.split(false).join(';') 18124, but requires almost same char and the left ones can be expressed easily [].constructor(4).join(';') 15794, but require fully same char String.prototype.repeat is not defined on IE and Maxthon, so not listed here
I believe something like Array(4).join(";")
should be almost always the best choice with repeated substrings (where Array
is [].constructor
).
Well there is also ";".repeat(3)
, although it doesn't work in older engines.
[IE9] unescape('false21false21false21'.split(false).join('%')) 9503 '!!!' 9366 [].filter.constructor('return({}+false).constructor.fromCharCode('+'33false33false33'.split(false)+')')() 9120
This is still longer than [].constructor(4).join("!")
. But I appreciate the idea.
It's not required to be the same char.
[IE9] '!' 6168c ([]+[]).constructor.fromCharCode(33) 5098c
I chose IE9 because Uppercase Letters are cheaper than in other environment without atob
Seems legit. This can be probably integrated in createCharCodesEncoding
somehow.
For the fromCharCode(list), [].filter.constructor('return(isNaN+false).constructor.fromCharCode('+'33false64false35'.split(false)+')')()
seems to be the best way, but not sure if best for every environment
Apparently, return String
... is cheaper for ["CAPITAL_HTML", "ENTRIES_OBJ"]
: https://jsfiddle.net/wrspc5g5/
Granted, that's a feature combination not found anywhere, but still.
ok I didn't realize 'S' can be expressed by ''['su'+'[Obje...'[2]]()[1]
^_^
So is there any more possible winner?
The unescape optimize seems not so simple, but still not so complex: for basic chars, it should be directly placed for % it should be false instead of false25 if won't be treated as an encoder and falsefalse20 if in code and may be treated as an encoder false should have one char encoded In my boot in jfuery, I used !1(it should have been !true) to mean false, cuz it's cheaper; but not false in string ... Same as byeval
That's because in IE, "".sub() + ""
produces <SUB></SUB>
rather than <sub></sub>
, but I can't think of how to make (isNaN+false).constructor
shorter, so there are no more winners by now.
Sure, the unescape
optimization wouldn't be too difficult. The problem is that I'm still fighting to fix some bugs and get old stuff straight, and I don't know when I'll have the time to implement all those improvements.
If there is something you want to help with I can try to guide you step-by-step, otherwise I promise I'll work on all of those, but I just can't say when.
I meant it's harder for me. I don't know too much about the code. Every time I want to see how you did, I unassemble the generated code - -
That's no surprise since I wrote nearly all of the code myself, and sometimes I must use a debugger to understand what I did. But if you have any questions just feel free to ask.
[IE9, isNaN fix]
[].filter.constructor('return(isNaN+false).constructor.fromCharCode(33,33,33,33,33)')()
8967c
'!!!!!'
8954c
[].filter.constructor('return(isNaN+false).constructor.fromCharCode(3'+[].slice.call('33')+[].slice.call('33')+[].slice.call('33')+[].slice.call('33')+'3)')()
8883c
[IE9]
'!@#$%' on jscrew.it(old version) 9507
'!@#$%' on local(new) 9019
[].filter.constructor("return status.constructor.fromCharCode(" + "33false64false35false36false37".split(false) + ")")()
8840
encode('"\\\\"','UNEVAL').length
3525
encode('"!"','UNEVAL').length
10706
encode('"错"','UNEVAL').length
7713
encode('[].filter.constructor("return\\"\\\\u9519\\"")()','UNEVAL').length
7713
encode('[].filter.constructor("return\\"\\\\u0021\\"")()','UNEVAL').length
7616
Sometimes it's better to use legacy octal escape sequences, e.g. \\41
instead of \\u0021
. These should be fine also in strict mode code since they are parsed by the Function
constructor, but I'll have to check with ES6 modules.
So '\040' should be eval("'\\040'") , not Function("return '\\040'")()?
https://github.com/fasttime/JScrewIt/issues/4
Update:
Function('"use strict";return eval')()('"\\040"')
returns ' ', even if in node v6.10.0 strict mode
I think that Function("return\"\\41\"")()
is just fine. It should evaluate to "!"
in any environment. As I understand it, #4 is about input parsing, and for that we can't assume that "\040" is inside a Function
argument or something.
I meant that even if you write "\040", it still doesn't run as normally run in strict mode
True, I'll have to see what can be done.
'fromCharCode'
16855
'from0har0ode'.split(0).join('C')
15273
well...
0 15273 debugger eval code:1:18 1 15290 debugger eval code:1:18 2 15276 debugger eval code:1:18 3 15251 debugger eval code:1:18 4 15293 debugger eval code:1:18 5 15270 debugger eval code:1:18 6 15308 debugger eval code:1:18 7 15293 debugger eval code:1:18 8 15315 debugger eval code:1:18 9 15291 b 18566 debugger eval code:1:31 c 17358 debugger eval code:1:31 g 18535 debugger eval code:1:31 i 17113 debugger eval code:1:31 j 19243 debugger eval code:1:31 k 20428 debugger eval code:1:31 l 17118 debugger eval code:1:31 n 17104 debugger eval code:1:31 p 20444 debugger eval code:1:31 q 20453 debugger eval code:1:31 s 17075 debugger eval code:1:31 t 17090 debugger eval code:1:31 u 17117 debugger eval code:1:31 v 17445 debugger eval code:1:31 w 20480 debugger eval code:1:31 x 20434 debugger eval code:1:31 y 17190 debugger eval code:1:31 z 20537
I like the fromCharCode
optimization because it works in all environments, it would be nice to have this in the next version. The shortest I could do is "from3har3o".split(3).join("C") + "d" + "e"
.
I'm not sure if it's useful because the situation that using fromCharCode
is better than escape/unescape
seems to only happen when C
is cheap (FONTCOLOR
)
fromCharCode
is most useful with strings of multiple characters (e.g. "XYZ"
).