HTML代码简加密

本文介绍了JSFuck,一种基于JavaScript基本元素的编程风格,它仅使用六个字符来执行代码。文章提供了一个在线工具,可以将JavaScript代码转换为JSFuck编码,并解释了如何在Node.js环境中运行JSFuck代码。此外,还提供了JSFuck的实现源码,帮助读者理解其工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码如下:

<html>

 <head></head>

 <body>

  <title>JSFuck</title>

  <meta name="description" content="JSFuck is an esoteric and educational programming style based on the atomic parts of JavaScript. It uses only six different characters to execute code.">

  <meta charset="utf-8">

  <meta property="og:image" content="http://www.jsfuck.com/preview.png">

  <meta name="viewport" content="width=device-width">

  <style>



    body {

      padding: 20px;

    }



    body, * {

      font-family: monospace;

      font-size: 14px;

      line-height: 1.4em;

    }



    h1 {

      font-size: 2em;

      position: absolute;

      top: 70px;

      font-weight: normal;

      left: 140px;

    }



    h2 {

      width: 90px;

      text-align: right;

      padding: 50px 5px 5px;

      background: #F0DB4E;

      color: #323230;

      font-weight: bold;

      font-size: 20px;

      line-height: 1em;

    }



    h3 {

      font-weight: bold;

    }



    p, li, textarea, .actions {

      width: 100%;

      max-width: 600px;

    }



    textarea {

      display: block;

      height: 200px;

      margin: 1em 0;

    }



    ul.pre li{

      white-space: pre;

    }



    .checkbox {

      display: inline-block;

    }



    .actions a {

      float: right;

    }



    .actions {

      clear: both;

    }



  </style>

  <h1>JSFuck</h1>

  <h2>()+<br>[]!</h2>

  <p>JSFuck是一种基于JavaScript的原子部分。它只使用六个不同的字符写和执行代码。</p>

  <p>它不依赖于浏览器,因此您甚至可以在Node.js上运行它。</p>

  <p>使用下面的表单转换您自己的脚本。取消选中“eval source”以取回一条普通的字符串。</p> <input id="input" type="text" value="alert(1)" placeholder="请输入代码"> <button id="encode" type="text">编码(不可包含中文)</button>

  <div class="checkbox"><input id="eval" type="checkbox" checked> <label for="eval">评估来源</label>

  </div>

  <div class="checkbox"><input id="scope" type="checkbox" checked> <label for="scope">在父范围内运行</label>

  </div> <textarea id="output"></textarea>

  <div class="actions"><span id="stats">…</span> <a id="run" href="#">模拟运行</a>

  </div>

  <script src="js/jsf.js"></script>

  <script>



    function $(id){

      return document.getElementById(id);

    }



    function encode(){

      var output = JSFuck.encode($("input").value, $("eval").checked, $("scope").checked);

      $("output").value = output;

      $("stats").innerHTML = output.length + " 个符号";

    }



    $("encode").onclick = encode;

    $("eval").onchange = encode;

    $("scope").onchange = encode;



    encode();



    $("run").onclick = function(){

      value = eval($("output").value);



      if (!$("eval").checked){

        alert('"' + value + '"');

      }

      return false;

    };

  </script>

  <script type="text/javascript">



    var _gaq = _gaq || [];

    _gaq.push(['_setAccount', 'UA-57649-11']);

    _gaq.push(['_trackPageview']);



    (function() {

      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;

      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';

      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);

    })();

  </script>

 </body>

</html>

再创建一个js文件夹里面放jsf.js文件,jsf.js文件里写:

/*! JSFuck 0.5.0 - http://jsfuck.com */



(function(self){

  const MIN = 32, MAX = 126;



  const SIMPLE = {

    'false': '![]',

    'true': '!![]',

    'undefined': '[][[]]',

    'NaN': '+[![]]',

    'Infinity': '+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]]+[+[]])' // +"1e1000"

  };



  const CONSTRUCTORS = {

    'Array': '[]',

    'Number': '(+[])',

    'String': '([]+[])',

    'Boolean': '(![])',

    'Function': '[]["flat"]',

    'RegExp': 'Function("return/"+false+"/")()',

    'Object': '[]["entries"]()'

  };



  const MAPPING = {

    'a': '(false+"")[1]',

    'b': '([]["entries"]()+"")[2]',

    'c': '([]["flat"]+"")[3]',

    'd': '(undefined+"")[2]',

    'e': '(true+"")[3]',

    'f': '(false+"")[0]',

    'g': '(false+[0]+String)[20]',

    'h': '(+(101))["to"+String["name"]](21)[1]',

    'i': '([false]+undefined)[10]',

    'j': '([]["entries"]()+"")[3]',

    'k': '(+(20))["to"+String["name"]](21)',

    'l': '(false+"")[2]',

    'm': '(Number+"")[11]',

    'n': '(undefined+"")[1]',

    'o': '(true+[]["flat"])[10]',

    'p': '(+(211))["to"+String["name"]](31)[1]',

    'q': '("")["fontcolor"]([0]+false+")[20]',

    'r': '(true+"")[1]',

    's': '(false+"")[3]',

    't': '(true+"")[0]',

    'u': '(undefined+"")[0]',

    'v': '(+(31))["to"+String["name"]](32)',

    'w': '(+(32))["to"+String["name"]](33)',

    'x': '(+(101))["to"+String["name"]](34)[1]',

    'y': '(NaN+[Infinity])[10]',

    'z': '(+(35))["to"+String["name"]](36)',



    'A': '(NaN+[]["entries"]())[11]',

    'B': '(+[]+Boolean)[10]',

    'C': 'Function("return escape")()(("")["italics"]())[2]',

    'D': 'Function("return escape")()([]["flat"])["slice"]("-1")',

    'E': '(RegExp+"")[12]',

    'F': '(+[]+Function)[10]',

    'G': '(false+Function("return Date")()())[30]',

    'H': null,

    'I': '(Infinity+"")[0]',

    'J': null,

    'K': null,

    'L': null,

    'M': '(true+Function("return Date")()())[30]',

    'N': '(NaN+"")[0]',

    'O': '(+[]+Object)[10]',

    'P': null,

    'Q': null,

    'R': '(+[]+RegExp)[10]',

    'S': '(+[]+String)[10]',

    'T': '(NaN+Function("return Date")()())[30]',

    'U': '(NaN+Object()["to"+String["name"]]["call"]())[11]',

    'V': null,

    'W': null,

    'X': null,

    'Y': null,

    'Z': null,



    ' ': '(NaN+[]["flat"])[11]',

    '!': null,

    '"': '("")["fontcolor"]()[12]',

    '#': null,

    '$': null,

    '%': 'Function("return escape")()([]["flat"])[21]',

    '&': '("")["fontcolor"](")[13]',

    '\'': null,

    '(': '([]["flat"]+"")[13]',

    ')': '([0]+false+[]["flat"])[20]',

    '*': null,

    '+': '(+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]])+[])[2]',

    ',': '[[]]["concat"]([[]])+""',

    '-': '(+(.+[0000001])+"")[2]',

    '.': '(+(+!+[]+[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+[!+[]+!+[]]+[+[]])+[])[+!+[]]',

    '/': '(false+[0])["italics"]()[10]',

    ':': '(RegExp()+"")[3]',

    ';': '("")["fontcolor"](NaN+")[21]',

    '<': '("")["italics"]()[0]',

    '=': '("")["fontcolor"]()[11]',

    '>': '("")["italics"]()[2]',

    '?': '(RegExp()+"")[2]',

    '@': null,

    '[': '([]["entries"]()+"")[0]',

    '\\': '(RegExp("/")+"")[1]',

    ']': '([]["entries"]()+"")[22]',

    '^': null,

    '_': null,

    '`': null,

    '{': '(true+[]["flat"])[20]',

    '|': null,

    '}': '([]["flat"]+"")["slice"]("-1")',

    '~': null

  };



  const GLOBAL = 'Function("return this")()';



  function fillMissingDigits(){

    var output, number, i;



    for (number = 0; number < 10; number++){



      output = "+[]";



      if (number > 0){ output = "+!" + output; }

      for (i = 1; i < number; i++){ output = "+!+[]" + output; }

      if (number > 1){ output = output.substr(1); }



      MAPPING[number] = "[" + output + "]";

    }

  }



  function replaceMap(){

    var character = "", value, i, key;



    function replace(pattern, replacement){

      value = value.replace(

        new RegExp(pattern, "gi"),

        replacement

      );

    }



    function digitReplacer(_,x) { return MAPPING[x]; }



    function numberReplacer(_,y) {

      var values = y.split("");

      var head = +(values.shift());

      var output = "+[]";



      if (head > 0){ output = "+!" + output; }

      for (i = 1; i < head; i++){ output = "+!+[]" + output; }

      if (head > 1){ output = output.substr(1); }



      return [output].concat(values).join("+").replace(/(\d)/g, digitReplacer);

    }



    for (i = MIN; i <= MAX; i++){

      character = String.fromCharCode(i);

      value = MAPPING[character];

      if(!value) {continue;}



      for (key in CONSTRUCTORS){

        replace("\\b" + key, CONSTRUCTORS[key] + '["constructor"]');

      }



      for (key in SIMPLE){

        replace(key, SIMPLE[key]);

      }



      replace('(\\d\\d+)', numberReplacer);

      replace('\\((\\d)\\)', digitReplacer);

      replace('\\[(\\d)\\]', digitReplacer);



      replace("GLOBAL", GLOBAL);

      replace('\\+""', "+[]");

      replace('""', "[]+[]");



      MAPPING[character] = value;

    }

  }



  function replaceStrings(){

    var regEx = /[^\[\]\(\)\!\+]{1}/g,

      all, value, missing,

      count = MAX - MIN;



    function findMissing(){

      var all, value, done = false;



      missing = {};



      for (all in MAPPING){



        value = MAPPING[all];



        if (value && value.match(regEx)){

          missing[all] = value;

          done = true;

        }

      }



      return done;

    }



    function mappingReplacer(a, b) {

      return b.split("").join("+");

    }



    function valueReplacer(c) {

      return missing[c] ? c : MAPPING[c];

    }



    for (all in MAPPING){

      if (MAPPING[all]){

        MAPPING[all] = MAPPING[all].replace(/\"([^\"]+)\"/gi, mappingReplacer);

      }

    }



    while (findMissing()){

      for (all in missing){

        value = MAPPING[all];

        value = value.replace(regEx, valueReplacer);



        MAPPING[all] = value;

        missing[all] = value;

      }



      if (count-- === 0){

        console.error("Could not compile the following chars:", missing);

      }

    }

  }



  function escapeSequence(c) {

    var cc = c.charCodeAt(0);

    if (cc < 256) {

      return '\\' + cc.toString(8);

    } else {

      var cc16 = cc.toString(16);

      return '\\u' + ('0000' + cc16).substring(cc16.length);  

    }

  }



  function escapeSequenceForReplace(c) {

    return escapeSequence(c).replace('\\', 't');

  }



  function encode(input, wrapWithEval, runInParentScope){

    var output = [];



    if (!input){

      return "";

    }



    var unmappped = ''

    for(var k in MAPPING) {

      if (MAPPING[k]){

        unmappped += k;

      }

    }

    unmappped = unmappped.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');

    unmappped = new RegExp('[^' + unmappped + ']','g');

    var unmappedCharactersCount = (input.match(unmappped) || []).length;

    if (unmappedCharactersCount > 1) {

      // Without this optimization one unmapped caracter has encoded length

      // of about 3600 characters. Every additional unmapped character adds 

      // 2000 to the total length. For example, the lenght of `~` is 3605, 

      // `~~` is 5600, and `~~~` is 7595.

      // 

      // The loader with replace has encoded length of about 5300 characters

      // and every additional character adds 100 to the total length. 

      // In the same example the length of `~~` becomes 5371 and `~~~` -- 5463.

      // 

      // So, when we have more than one unmapped character we want to encode whole input

      // except select characters (that have encoded length less than about 70)

      // into an escape sequence.

      //

      // NOTE: `t` should be escaped!

      input = input.replace(/[^0123456789.adefilnrsuN]/g, escapeSequenceForReplace);

    } else if (unmappedCharactersCount > 0) {

      //Because we will wrap the input into a string we need to escape Backslash 

      // and Double quote characters (we do not need to worry about other characters 

      // because they are not mapped explicitly).

      // The JSFuck-encoded representation of `\` is 2121 symbols,

      // so esacped `\` is 4243 symbols and escaped `"` is 2261 symbols

      // however the escape sequence of that characters are 

      // 2168 and 2155 symbols respectively, so it's more practical to 

      // rewrite them as escape sequences.

      input = input.replace(/["\\]/g, escapeSequence);

      //Convert all unmapped characters to escape sequence

      input = input.replace(unmappped, escapeSequence);

    }



    var r = "";

    for (var i in SIMPLE) {

      r += i + "|";

    }

    r+= ".";



    input.replace(new RegExp(r, 'g'), function(c) {

      var replacement = SIMPLE[c];

      if (replacement) {

        output.push("(" + replacement + "+[])");

      } else {

        replacement = MAPPING[c];

        if (replacement){

          output.push(replacement);

        } else {

          throw new Error('Found unmapped character: ' + c);

        }

      }

    });



    output = output.join("+");



    if (/^\d$/.test(input)){

      output += "+[]";

    }



    if (unmappedCharactersCount > 1) {

      // replace `t` with `\\`

      output = "(" + output + ")[" + encode("split") + "](" + encode ("t") + ")[" + encode("join") +"](" + encode("\\") + ")";

    }



    if (unmappedCharactersCount > 0) {

      output = "[][" + encode("flat") + "]"+

      "[" + encode("constructor") + "]" +

      "(" + encode("return\"") + "+" + output + "+" + encode("\"") + ")()";

    }



    if (wrapWithEval){

      if (runInParentScope){

        output = "[][" + encode("flat") + "]" +

          "[" + encode("constructor") + "]" +

          "(" + encode("return eval") + ")()" +

          "(" + output + ")";

      } else {

        output = "[][" + encode("flat") + "]" +

          "[" + encode("constructor") + "]" +

          "(" + output + ")()";

      }

    }



    return output;

  }



  fillMissingDigits();

  replaceMap();

  replaceStrings();



  self.JSFuck = {

    encode: encode

  };

})(typeof(exports) === "undefined" ? window : exports);

Footer

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

director Carter

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值