JavaScript(不可逆加密)近似解密

前言


目前盈包,我們?nèi)粘g覽的網(wǎng)站中,日常會(huì)有防止網(wǎng)站被黑客克隆網(wǎng)站醇王、爬取網(wǎng)站呢燥、壓縮代碼等的需求,都會(huì)使用一些方法對(duì)源碼進(jìn)行處理寓娩。其中叛氨,有的使用Webpack對(duì)JavaScript代碼進(jìn)行打包,也有使用js代碼加密的方法棘伴。因此寞埠,本篇文章將會(huì)對(duì)js代碼加密進(jìn)行一個(gè)簡(jiǎn)單的分析,并主要針對(duì)不可逆加密提供一些常用的近似解密思路焊夸。

JavaScript加密分析


首先仁连,我們能確定的一件事是,無(wú)論加密與否阱穗,加載的js文件都能夠在瀏覽器其中執(zhí)行怖糊,并得到對(duì)應(yīng)的結(jié)果帅容。

有的思路是根據(jù)一些參數(shù)特殊處理進(jìn)行加密,也有的是跟后端達(dá)成協(xié)議伍伤,進(jìn)行加解密的方式得出結(jié)果并執(zhí)行。但是遣钳,后者的方案會(huì)對(duì)我們的服務(wù)造成額外的壓力扰魂,因此使用前者更為主流。因此本篇文章只討論前者這種的方案蕴茴。
近似解密的方案是基于代碼邏輯正確劝评、提高可讀性的方向進(jìn)行的。

這里列舉了一些加密方式(可逆的):

  • 最簡(jiǎn)單的加密解密
  • 轉(zhuǎn)義字符""的妙用
  • 使用Microsoft出品的腳本編碼器Script Encoder來(lái)進(jìn)行編碼
  • 任意添加NUL空字符(十六進(jìn)制00H)
  • 無(wú)用內(nèi)容混亂以及換行空格TAB大法
  • 自寫解密函數(shù)法
    對(duì)應(yīng)的加解密思路可以看這里倦淀,我就不一一列舉了

不可逆的加密方式:

根據(jù)各種指定的參數(shù)混淆+不可逆的算法進(jìn)行加密https://www.jsjiami.com/
但是蒋畜,即使是不可逆加密過(guò)后,得出的結(jié)果也是能正常執(zhí)行的撞叽,符合JavaScript的語(yǔ)法的姻成,因此,我們就可以就此對(duì)源碼進(jìn)行翻譯愿棋。

舉個(gè)栗子并分享一個(gè)思路

舉個(gè)栗子

var __encode = 'jsjiami.com', _a = {}, _0xb483 = ["\x5F\x64\x65\x63\x6F\x64\x65", "\x68\x74\x74\x70\x3A\x2F\x2F\x77\x77\x77\x2E\x73\x6F\x6A\x73\x6F\x6E\x2E\x63\x6F\x6D\x2F\x6A\x61\x76\x61\x73\x63\x72\x69\x70\x74\x6F\x62\x66\x75\x73\x63\x61\x74\x6F\x72\x2E\x68\x74\x6D\x6C"]; (function (_0xd642x1) { _0xd642x1[_0xb483[0]] = _0xb483[1] })(_a); var __Oxb24bc = ["\x6C\x69\x74\x65\x2D\x61\x6E\x64\x72\x6F\x69\x64\x26", "\x73\x74\x72\x69\x6E\x67\x69\x66\x79", "\x26\x61\x6E\x64\x72\x6F\x69\x64\x26\x33\x2E\x31\x2E\x30\x26", "\x26", "\x26\x38\x34\x36\x63\x34\x63\x33\x32\x64\x61\x65\x39\x31\x30\x65\x66", "\x31\x32\x61\x65\x61\x36\x35\x38\x66\x37\x36\x65\x34\x35\x33\x66\x61\x66\x38\x30\x33\x64\x31\x35\x63\x34\x30\x61\x37\x32\x65\x30", "\x69\x73\x4E\x6F\x64\x65", "\x63\x72\x79\x70\x74\x6F\x2D\x6A\x73", "", "\x61\x70\x69\x3F\x66\x75\x6E\x63\x74\x69\x6F\x6E\x49\x64\x3D", "\x26\x62\x6F\x64\x79\x3D", "\x26\x61\x70\x70\x69\x64\x3D\x6C\x69\x74\x65\x2D\x61\x6E\x64\x72\x6F\x69\x64\x26\x63\x6C\x69\x65\x6E\x74\x3D\x61\x6E\x64\x72\x6F\x69\x64\x26\x75\x75\x69\x64\x3D\x38\x34\x36\x63\x34\x63\x33\x32\x64\x61\x65\x39\x31\x30\x65\x66\x26\x63\x6C\x69\x65\x6E\x74\x56\x65\x72\x73\x69\x6F\x6E\x3D\x33\x2E\x31\x2E\x30\x26\x74\x3D", "\x26\x73\x69\x67\x6E\x3D", "\x61\x70\x69\x2E\x6D\x2E\x6A\x64\x2E\x63\x6F\x6D", "\x2A\x2F\x2A", "\x52\x4E", "\x4A\x44\x4D\x6F\x62\x69\x6C\x65\x4C\x69\x74\x65\x2F\x33\x2E\x31\x2E\x30\x20\x28\x69\x50\x61\x64\x3B\x20\x69\x4F\x53\x20\x31\x34\x2E\x34\x3B\x20\x53\x63\x61\x6C\x65\x2F\x32\x2E\x30\x30\x29", "\x7A\x68\x2D\x48\x61\x6E\x73\x2D\x43\x4E\x3B\x71\x3D\x31\x2C\x20\x6A\x61\x2D\x43\x4E\x3B\x71\x3D\x30\x2E\x39", "\x75\x6E\x64\x65\x66\x69\x6E\x65\x64", "\x6C\x6F\x67", "\u5220\u9664", "\u7248\u672C\u53F7\uFF0C\x6A\x73\u4F1A\u5B9A", "\u671F\u5F39\u7A97\uFF0C", "\u8FD8\u8BF7\u652F\u6301\u6211\u4EEC\u7684\u5DE5\u4F5C", "\x6A\x73\x6A\x69\x61", "\x6D\x69\x2E\x63\x6F\x6D"]; function taskUrl(_0x7683x2, _0x7683x3 = {}) { let _0x7683x4 = + new Date(); let _0x7683x5 = `${__Oxb24bc[0x0]}${JSON[__Oxb24bc[0x1]](_0x7683x3)}${__Oxb24bc[0x2]}${_0x7683x2}${__Oxb24bc[0x3]}${_0x7683x4}${__Oxb24bc[0x4]}`; let _0x7683x6 = __Oxb24bc[0x5]; const _0x7683x7 = $[__Oxb24bc[0x6]]() ? require(__Oxb24bc[0x7]) : CryptoJS; let _0x7683x8 = _0x7683x7.HmacSHA256(_0x7683x5, _0x7683x6).toString(); return { url: `${__Oxb24bc[0x8]}${JD_API_HOST}${__Oxb24bc[0x9]}${_0x7683x2}${__Oxb24bc[0xa]}${escape(JSON[__Oxb24bc[0x1]](_0x7683x3))}${__Oxb24bc[0xb]}${_0x7683x4}${__Oxb24bc[0xc]}${_0x7683x8}${__Oxb24bc[0x8]}`, headers: { '\x48\x6F\x73\x74': __Oxb24bc[0xd], '\x61\x63\x63\x65\x70\x74': __Oxb24bc[0xe], '\x6B\x65\x72\x6E\x65\x6C\x70\x6C\x61\x74\x66\x6F\x72\x6D': __Oxb24bc[0xf], '\x75\x73\x65\x72\x2D\x61\x67\x65\x6E\x74': __Oxb24bc[0x10], '\x61\x63\x63\x65\x70\x74\x2D\x6C\x61\x6E\x67\x75\x61\x67\x65': __Oxb24bc[0x11], '\x43\x6F\x6F\x6B\x69\x65': cookie } } } (function (_0x7683x9, _0x7683xa, _0x7683xb, _0x7683xc, _0x7683xd, _0x7683xe) { _0x7683xe = __Oxb24bc[0x12]; _0x7683xc = function (_0x7683xf) { if (typeof alert !== _0x7683xe) { alert(_0x7683xf) }; if (typeof console !== _0x7683xe) { console[__Oxb24bc[0x13]](_0x7683xf) } }; _0x7683xb = function (_0x7683x7, _0x7683x9) { return _0x7683x7 + _0x7683x9 }; _0x7683xd = _0x7683xb(__Oxb24bc[0x14], _0x7683xb(_0x7683xb(__Oxb24bc[0x15], __Oxb24bc[0x16]), __Oxb24bc[0x17])); try { _0x7683x9 = __encode; if (!(typeof _0x7683x9 !== _0x7683xe && _0x7683x9 === _0x7683xb(__Oxb24bc[0x18], __Oxb24bc[0x19]))) { _0x7683xc(_0x7683xd) } } catch (e) { _0x7683xc(_0x7683xd) } })({})

首先

看到上面的內(nèi)容科展,分析得出里面包含著\x5F\x64\x65\x63\x6F\x64\x65\u5220\u9664這些特殊字符串糠雨,我們可以得出才睹,里面的混淆會(huì)是進(jìn)行過(guò)unicode和16進(jìn)制的轉(zhuǎn)換得出的,因此甘邀,我們可以先對(duì)此先進(jìn)行一次轉(zhuǎn)換琅攘,最終得出的結(jié)果是

var __encode = 'jsjiami.com',
    _a = {},
    _0xb483 = ["_decode", "http://www.sojson.com/javascriptobfuscator.html"];
(function(_0xd642x1) {
    _0xd642x1[_0xb483[0]] = _0xb483[1]
})(_a);
var __Oxb24bc = ["lite-android&", "stringify", "&android&3.1.0&", "&", "&846c4c32dae910ef", "12aea658f76e453faf803d15c40a72e0", "isNode", "crypto-js", "", "api?functionId=", "&body=", "&appid=lite-android&client=android&uuid=846c4c32dae910ef&clientVersion=3.1.0&t=", "&sign=", "api.m.jd.com", "*/*", "RN", "JDMobileLite/3.1.0 (iPad; iOS 14.4; Scale/2.00)", "zh-Hans-CN;q=1, ja-CN;q=0.9", "undefined", "log", "刪除", "版本號(hào),js會(huì)定", "期彈窗松邪,", "還請(qǐng)支持我們的工作", "jsjia", "mi.com"];

function taskUrl(_0x7683x2, _0x7683x3 = {}) {
    let _0x7683x4 = +new Date();
    let _0x7683x5 = `${__Oxb24bc[0x0]}${JSON[__Oxb24bc[0x1]](_0x7683x3)}${__Oxb24bc[0x2]}${_0x7683x2}${__Oxb24bc[0x3]}${_0x7683x4}${__Oxb24bc[0x4]}`;
    let _0x7683x6 = __Oxb24bc[0x5];
    const _0x7683x7 = $[__Oxb24bc[0x6]]() ? require(__Oxb24bc[0x7]) : CryptoJS;
    let _0x7683x8 = _0x7683x7.HmacSHA256(_0x7683x5, _0x7683x6).toString();
    return {
        url: `${__Oxb24bc[0x8]}${JD_API_HOST}${__Oxb24bc[0x9]}${_0x7683x2}${__Oxb24bc[0xa]}${escape(JSON[__Oxb24bc[0x1]](_0x7683x3))}${__Oxb24bc[0xb]}${_0x7683x4}${__Oxb24bc[0xc]}${_0x7683x8}${__Oxb24bc[0x8]}`,
        headers: {
            'Host': __Oxb24bc[0xd],
            'accept': __Oxb24bc[0xe],
            'kernelplatform': __Oxb24bc[0xf],
            'user-agent': __Oxb24bc[0x10],
            'accept-language': __Oxb24bc[0x11],
            'Cookie': cookie
        }
    }
}(function(_0x7683x9, _0x7683xa, _0x7683xb, _0x7683xc, _0x7683xd, _0x7683xe) {
    _0x7683xe = __Oxb24bc[0x12];
    _0x7683xc = function(_0x7683xf) {
        if (typeof alert !== _0x7683xe) {
            alert(_0x7683xf)
        };
        if (typeof console !== _0x7683xe) {
            console[__Oxb24bc[0x13]](_0x7683xf)
        }
    };
    _0x7683xb = function(_0x7683x7, _0x7683x9) {
        return _0x7683x7 + _0x7683x9
    };
    _0x7683xd = _0x7683xb(__Oxb24bc[0x14], _0x7683xb(_0x7683xb(__Oxb24bc[0x15], __Oxb24bc[0x16]), __Oxb24bc[0x17]));
    try {
        _0x7683x9 = __encode;
        if (!(typeof _0x7683x9 !== _0x7683xe && _0x7683x9 === _0x7683xb(__Oxb24bc[0x18], __Oxb24bc[0x19]))) {
            _0x7683xc(_0x7683xd)
        }
    } catch (e) {
        _0x7683xc(_0x7683xd)
    }
})({})

到此

我們大致上已把對(duì)應(yīng)的內(nèi)容簡(jiǎn)單地解密出來(lái)了坞琴。但是,目前而言测摔,源碼的可讀性比較差置济,我們可以再觀察一下》姘耍可以發(fā)現(xiàn)浙于,在開頭已定義了__Oxb24bc這個(gè)數(shù)組變量,文中的部分變量也使用到數(shù)組中的內(nèi)容挟纱,因此羞酗,我們可以根據(jù)這樣轉(zhuǎn)化一波∥煞可以得出一下:

var __encode = 'jsjiami.com',
  _a = {},
  _0xb483 = ["_decode", "http://www.sojson.com/javascriptobfuscator.html"];
(function (_0xd642x1) {
  _0xd642x1["_decode"] = "http://www.sojson.com/javascriptobfuscator.html"
})(_a);
var __Oxb24bc = ["lite-android&", "stringify", "&android&3.1.0&", "&", "&846c4c32dae910ef", "12aea658f76e453faf803d15c40a72e0", "isNode", "crypto-js", "", "api?functionId=", "&body=", "&appid=lite-android&client=android&uuid=846c4c32dae910ef&clientVersion=3.1.0&t=", "&sign=", "api.m.jd.com", "*/*", "RN", "JDMobileLite/3.1.0 (iPad; iOS 14.4; Scale/2.00)", "zh-Hans-CN;q=1, ja-CN;q=0.9", "undefined", "log", "刪除", "版本號(hào)檀轨,js會(huì)定", "期彈窗胸竞,", "還請(qǐng)支持我們的工作", "jsjia", "mi.com"];

function taskUrl(_0x7683x2, _0x7683x3 = {}) {
  let _0x7683x4 = +new Date();
  let _0x7683x5 = `lite-android&${JSON.stringify(_0x7683x3)}&android&3.1.0&${_0x7683x2}&${_0x7683x4}&846c4c32dae910ef`;
  let _0x7683x6 = "12aea658f76e453faf803d15c40a72e0";
  const _0x7683x7 = $.isNode() ? require("crypto-js") : CryptoJS;
  let _0x7683x8 = _0x7683x7.HmacSHA256(_0x7683x5, _0x7683x6).toString();
  return {
    url: ""+`${JD_API_HOST}api?functionId=${_0x7683x2}&body=${escape(JSON.stringify(_0x7683x3))}&appid=lite-android&client=android&uuid=846c4c32dae910ef&clientVersion=3.1.0&t=${_0x7683x4}&sign=${_0x7683x8}`+"",
    headers: {
      'Host': 'api.m.jd.com',
      'accept': '*/*',
      'kernelplatform': 'RN',
      'user-agent': 'JDMobileLite/3.1.0 (iPad; iOS 14.4; Scale/2.00)',
      'accept-language': 'zh-Hans-CN;q=1, ja-CN;q=0.9',
      'Cookie': cookie
    }
  }
}
(function (_0x7683x9, _0x7683xa, _0x7683xb, _0x7683xc, _0x7683xd, _0x7683xe) {
  _0x7683xe = 'undefined';
  _0x7683xc = function (_0x7683xf) {
    if (typeof alert !== _0x7683xe) {
      alert(_0x7683xf)
    };
    console.log(console)
    if (typeof console !== _0x7683xe) {
      console.log(_0x7683xf)
    }
  };
  _0x7683xb = function (_0x7683x7, _0x7683x9) {
    return _0x7683x7 + _0x7683x9
  };
  _0x7683xd = _0x7683xb('刪除', _0x7683xb(_0x7683xb('版本號(hào),js會(huì)定', '期彈窗参萄,'), '還請(qǐng)支持我們的工作'));
  try {
    _0x7683x9 = __encode;
    if (!(typeof _0x7683x9 !== _0x7683xe && _0x7683x9 === _0x7683xb('jsjia', 'mi.com'))) {
      _0x7683xc(_0x7683xd)
    }
  } catch (e) {
    _0x7683xc(_0x7683xd)
  }
})({})

其中卫枝,我們可以看到_0x7683xb這個(gè)方法,其實(shí)實(shí)際上處理的操作是在做字符串拼接讹挎,對(duì)此可以簡(jiǎn)化整理一下校赤,并得出:

var __encode = 'jsjiami.com',
  _a = {},
  _0xb483 = ["_decode", "http://www.sojson.com/javascriptobfuscator.html"];
(function (_0xd642x1) {
  _0xd642x1["_decode"] = "http://www.sojson.com/javascriptobfuscator.html"
})(_a);
var __Oxb24bc = ["lite-android&", "stringify", "&android&3.1.0&", "&", "&846c4c32dae910ef", "12aea658f76e453faf803d15c40a72e0", "isNode", "crypto-js", "", "api?functionId=", "&body=", "&appid=lite-android&client=android&uuid=846c4c32dae910ef&clientVersion=3.1.0&t=", "&sign=", "api.m.jd.com", "*/*", "RN", "JDMobileLite/3.1.0 (iPad; iOS 14.4; Scale/2.00)", "zh-Hans-CN;q=1, ja-CN;q=0.9", "undefined", "log", "刪除", "版本號(hào),js會(huì)定", "期彈窗筒溃,", "還請(qǐng)支持我們的工作", "jsjia", "mi.com"];

function taskUrl(_0x7683x2, _0x7683x3 = {}) {
  let _0x7683x4 = +new Date();
  let _0x7683x5 = `lite-android&${JSON.stringify(_0x7683x3)}&android&3.1.0&${_0x7683x2}&${_0x7683x4}&846c4c32dae910ef`;
  let _0x7683x6 = "12aea658f76e453faf803d15c40a72e0";
  const _0x7683x7 = $.isNode() ? require("crypto-js") : CryptoJS;
  let _0x7683x8 = _0x7683x7.HmacSHA256(_0x7683x5, _0x7683x6).toString();
  return {
    url: ""+`${JD_API_HOST}api?functionId=${_0x7683x2}&body=${escape(JSON.stringify(_0x7683x3))}&appid=lite-android&client=android&uuid=846c4c32dae910ef&clientVersion=3.1.0&t=${_0x7683x4}&sign=${_0x7683x8}`+"",
    headers: {
      'Host': 'api.m.jd.com',
      'accept': '*/*',
      'kernelplatform': 'RN',
      'user-agent': 'JDMobileLite/3.1.0 (iPad; iOS 14.4; Scale/2.00)',
      'accept-language': 'zh-Hans-CN;q=1, ja-CN;q=0.9',
      'Cookie': cookie
    }
  }
}
(function (_0x7683x9, _0x7683xa, _0x7683xc, _0x7683xd, _0x7683xe) {
  _0x7683xe = 'undefined';
  _0x7683xc = function (_0x7683xf) {
    if (typeof alert !== _0x7683xe) {
      alert(_0x7683xf)
    };
    console.log(console)
    if (typeof console !== _0x7683xe) {
      console.log(_0x7683xf)
    }
  };
  _0x7683xd = '刪除版本號(hào)马篮,js會(huì)定期彈窗,還請(qǐng)支持我們的工作';
  try {
    _0x7683x9 = __encode;
    if (!(typeof _0x7683x9 !== _0x7683xe && _0x7683x9 === 'jsjiami.com')) {
      _0x7683xc(_0x7683xd)
    }
  } catch (e) {
    _0x7683xc(_0x7683xd)
  }
})({})

對(duì)此怜奖,基本已經(jīng)翻譯完成浑测,剩下的給這些_0x7683開頭的變量換個(gè)名字,讓他看起來(lái)更加舒服歪玲,在這里迁央,我就大致根據(jù)這些變量定義的數(shù)據(jù)起個(gè)名字,并簡(jiǎn)化一些累贅的代碼~
Magic~

var __encode = 'jsjiami.com',
  _a = {};
(function (_0xd642x1) {
  _0xd642x1["_decode"] = "http://www.sojson.com/javascriptobfuscator.html"
})(_a);
var __Oxb24bc = ["lite-android&", "stringify", "&android&3.1.0&", "&", "&846c4c32dae910ef", "12aea658f76e453faf803d15c40a72e0", "isNode", "crypto-js", "", "api?functionId=", "&body=", "&appid=lite-android&client=android&uuid=846c4c32dae910ef&clientVersion=3.1.0&t=", "&sign=", "api.m.jd.com", "*/*", "RN", "JDMobileLite/3.1.0 (iPad; iOS 14.4; Scale/2.00)", "zh-Hans-CN;q=1, ja-CN;q=0.9", "undefined", "log", "刪除", "版本號(hào)读慎,js會(huì)定", "期彈窗漱贱,", "還請(qǐng)支持我們的工作", "jsjia", "mi.com"];

function taskUrl(id, data = {}) {
  let time = +new Date();
  let form = `lite-android&${JSON.stringify(data)}&android&3.1.0&${id}&${time}&846c4c32dae910ef`;
  let code = "12aea658f76e453faf803d15c40a72e0";
  const sha = $.isNode() ? require("crypto-js") : CryptoJS;
  let sign = sha.HmacSHA256(form, code).toString();
  return {
    url: ""+`${JD_API_HOST}api?functionId=${id}&body=${escape(JSON.stringify(data))}&appid=lite-android&client=android&uuid=846c4c32dae910ef&clientVersion=3.1.0&t=${time}&sign=${sign}`+"",
    headers: {
      'Host': 'api.m.jd.com',
      'accept': '*/*',
      'kernelplatform': 'RN',
      'user-agent': 'JDMobileLite/3.1.0 (iPad; iOS 14.4; Scale/2.00)',
      'accept-language': 'zh-Hans-CN;q=1, ja-CN;q=0.9',
      'Cookie': cookie
    }
  }
}
(function (encode, alarm) {
  alarm = function (msg) {
    if (typeof alert !== 'undefined') {
      alert(msg)
    };
    if (typeof console !== 'undefined') {
      console.log(msg)
    }
  };
  try {
    encode = __encode;
    if (!(typeof encode !== 'undefined' && encode === 'jsjiami.com')) {
      alarm('刪除版本號(hào),js會(huì)定期彈窗夭委,還請(qǐng)支持我們的工作')
    }
  } catch (e) {
    alarm('刪除版本號(hào)幅狮,js會(huì)定期彈窗,還請(qǐng)支持我們的工作')
  }
})({})

就此株灸,解密已經(jīng)處理好了

或許崇摄,寫到這里,會(huì)有很多朋友會(huì)問(wèn)
Q:為什么_0x7683開頭的變量沒(méi)不能直接解析出他具體的變量名是什么呢慌烧?
A:首先逐抑,這個(gè)變量的生成具體是根據(jù)哪些參數(shù)算出來(lái)的,我們不清楚屹蚊,想要去解開他需要嘗試各種組合厕氨,有可能有朋友說(shuō),一看就知道是進(jìn)制轉(zhuǎn)換出來(lái)的汹粤。這么想命斧,沒(méi)錯(cuò),但是嘱兼,具體是哪個(gè)進(jìn)制国葬,你還要不斷的嘗試,而且,其實(shí)這只是一個(gè)變量名汇四,到最后也不會(huì)影響里面的邏輯接奈。因此,為了高效而言通孽,還是直接起一個(gè)新的名字就好了序宦。(只是審查源碼的邏輯,不要太糾結(jié))


工具方法(網(wǎng)上)

下面這個(gè)方法可以直接把數(shù)組的內(nèi)容在文中替換利虫,并且挨厚,把xxx["yyy"]的格式轉(zhuǎn)為xxx.yyy的格式。其中糠惫,__Oxb7f82需要根據(jù)實(shí)際情況下的字符串?dāng)?shù)組對(duì)應(yīng)的變量進(jìn)行替換,以本文的栗子為例是__Oxb24bc,其中code的數(shù)據(jù)是對(duì)應(yīng)需要解碼的js數(shù)據(jù)钉疫。

console.log(code.replace(/__Oxb7f82\[0x[\da-f]+\]/g,a=>{
a=`"${eval(a).replace(/"/g,"\"")}"`;
console.log(a);
return a
}).replace(/\[s*['"][^"']+['"]\s*\]/g,a=>{
a=a.trim();
a=a.substring(2,a.length-2)
console.log(a);
return "."+a
}))

寫到最后硼讽,這篇文章僅做技術(shù)分享,若涉及版權(quán)和信息安全問(wèn)題牲阁,請(qǐng)聯(lián)系小編會(huì)馬上處理~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末固阁,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子城菊,更是在濱河造成了極大的恐慌备燃,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凌唬,死亡現(xiàn)場(chǎng)離奇詭異并齐,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)客税,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門况褪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人更耻,你說(shuō)我怎么就攤上這事测垛。” “怎么了秧均?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵食侮,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我目胡,道長(zhǎng)锯七,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任讶隐,我火速辦了婚禮起胰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己效五,他們只是感情好地消,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著畏妖,像睡著了一般脉执。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上戒劫,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天半夷,我揣著相機(jī)與錄音,去河邊找鬼迅细。 笑死巫橄,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的茵典。 我是一名探鬼主播湘换,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼统阿!你這毒婦竟也來(lái)了彩倚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤扶平,失蹤者是張志新(化名)和其女友劉穎帆离,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體结澄,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡哥谷,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了概而。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片呼巷。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖赎瑰,靈堂內(nèi)的尸體忽然破棺而出王悍,到底是詐尸還是另有隱情,我是刑警寧澤餐曼,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布压储,位于F島的核電站,受9級(jí)特大地震影響源譬,放射性物質(zhì)發(fā)生泄漏集惋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一踩娘、第九天 我趴在偏房一處隱蔽的房頂上張望刮刑。 院中可真熱鬧,春花似錦、人聲如沸雷绢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)翘紊。三九已至蔽氨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間帆疟,已是汗流浹背鹉究。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留踪宠,地道東北人自赔。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像柳琢,于是被迫代替她去往敵國(guó)和親匿级。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容