Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I need help deobfuscating some Javascript. I've been trying to decode it for hours but I've gotten nowhere.
function divulge() {
eval(function (p, a, c, k, e, r) {
e = function (c) {
return (c < a ? '' : e(parseInt(c / a))) + ((c = c % a) > 35 ? String.fromCharCode(c + 29) : c.toString(36))
};
if (!''.replace(/^/, String)) {
while (c--) r[e(c)] = k[c] || e(c);
k = [
function (e) {
return r[e]
}
];
e = function () {
return '\\w+'
};
c = 1
};
while (c--) if (k[c]) p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c]);
return p
}('19 k=["\\N\\U\\O\\V\\P\\F\\a\\W\\a\\Q\\a\\t\\a\\o\\a\\g\\a\\X\\a\\x\\a\\u\\a\\y\\a\\l\\a\\t\\a\\p\\a\\u\\a\\g\\a\\o\\a\\l\\a\\p\\a\\m\\a\\f\\a\\o\\a\\g\\a\\o\\a\\p\\a\\v\\a\\f\\a\\g\\a\\o\\a\\f\\a\\y\\a\\m\\a\\f\\a\\l\\a\\g\\a\\x\\a\\u\\a\\Y\\a\\f\\a\\m\\a\\g\\a\\o\\a\\p\\a\\v\\a\\f\\a\\g\\a\\n\\a\\m\\a\\Z\\a\\t\\a\\l\\a\\m\\a\\n\\a\\m\\a\\c\\a\\g\\a\\r\\a\\n\\a\\m\\a\\t\\a\\n\\a\\Z\\a\\z\\a\\f\\a\\g\\a\\1a\\a\\Q\\a\\p\\a\\o\\a\\f\\a\\g\\a\\u\\a\\n\\a\\v\\a\\f\\a\\g\\a\\1b\\a\\g\\a\\o\\a\\Q\\a\\n\\a\\z\\a\\z\\a\\g\\a\\u\\a\\p\\a\\l\\a\\g\\a\\m\\a\\f\\a\\r\\a\\f\\a\\n\\a\\z\\a\\1c\\F\\1d\\F\\a\\d\\a\\e\\a\\1e\\a\\d\\a\\h\\a\\G\\a\\d\\a\\h\\a\\G\\a\\d\\a\\h\\a\\H\\a\\d\\a\\i\\a\\10\\a\\d\\a\\s\\a\\A\\a\\d\\a\\s\\a\\A\\a\\d\\a\\h\\a\\i\\a\\d\\a\\e\\a\\w\\a\\d\\a\\e\\a\\h\\a\\d\\a\\e\\a\\B\\a\\d\\a\\e\\a\\w\\a\\d\\a\\e\\a\\B\\a\\d\\a\\s\\a\\B\\a\\d\\a\\e\\a\\i\\a\\d\\a\\e\\a\\11\\a\\d\\a\\e\\a\\12\\a\\d\\a\\h\\a\\i\\a\\d\\a\\e\\a\\i\\a\\d\\a\\h\\a\\i\\a\\d\\a\\e\\a\\i\\a\\d\\a\\s\\a\\B\\a\\d\\a\\e\\a\\A\\a\\d\\a\\h\\a\\s\\a\\d\\a\\e\\a\\h\\a\\d\\a\\s\\a\\A\\a\\d\\a\\h\\a\\i\\a\\d\\a\\e\\a\\C\\a\\d\\a\\e\\a\\i\\a\\d\\a\\h\\a\\s\\a\\d\\a\\e\\a\\C\\a\\d\\a\\h\\a\\G\\a\\d\\a\\h\\a\\i\\F\\R\\S\\1f\\13\\O\\P\\I\\R\\14\\S\\N\\U\\1g\\V\\1h\\13\\O\\P\\D\\R\\14\\S","\\b","\\w\\y\\v\\B\\C","\\b\\b\\c\\d\\h\\b\\c\\e\\f\\b\\c\\d\\I\\b\\c\\e\\i\\b\\c\\f\\h\\b\\c\\e\\e\\b\\c\\i\\e\\b\\c\\i\\d\\b\\c\\f\\D\\b\\c\\e\\d\\b\\c\\f\\12\\b\\c\\f\\11\\b\\c\\i\\g\\b\\c\\f\\m\\b\\c\\f\\H\\b\\c\\g\\f\\b\\c\\g\\h\\b\\1i\\I\\c\\d\\p\\f\\t\\b\\c\\f\\o\\b\\c\\f\\10\\b\\c\\e\\g\\b\\X\\n\\r\\b\\c\\i\\h\\b\\c\\f\\e\\b\\c\\f\\d\\b\\c\\i\\f\\b\\c\\e\\m\\b\\c\\e\\h\\b\\c\\h\\g\\b\\c\\f\\f\\b\\c\\f\\g\\b\\c\\i\\m\\b\\c\\i\\i\\b\\c\\g\\m\\b\\c\\d\\D\\b\\c\\e\\o\\b\\c\\e\\I\\b\\c\\g\\D\\b\\c\\e\\D\\b\\c\\g\\g\\b\\n\\v\\l\\r\\C\\b\\w\\l\\p\\r\\l\\C\\x\\w\\b\\W\\N\\l\\w\\p\\n\\y\\l","","\\t\\r\\x\\G\\H\\A\\n\\r\\H\\x\\u\\l","\\r\\l\\y\\v\\n\\p\\l","\\a\\Y\\1j","\\a\\s","\\z"];1k(J(K,L,j,E,q,T){q=J(j){M(j<L?k[4]:q(1l(j/L)))+((j=j%L)>1m?15[k[5]](j+1n):j.1o(1p))};16(!k[4][k[6]](/^/,15)){17(j--){T[q(j)]=E[j]||q(j)};E=[J(q){M T[q]}];q=J(){M k[7]};j=1};17(j--){16(E[j]){K=K[k[6]](1q 1r(k[8]+q(j)+k[8],k[9]),E[j])}};M K}(k[0],18,18,k[3][k[2]](k[1]),0,{}));', 62, 90, '||||||||||x5C|x7C|x78|x32|x33|x36|x34|x35|x37|_0xd4b0x3|_0x6159|x65|x39|x61|x38|x63|_0xd4b0x5|x72|x62|x66|x64|x6C|x73|x6F|x70|x67|x68|x69|x74|x31|_0xd4b0x4|x22|x6D|x43|x30|function|_0xd4b0x1|_0xd4b0x2|return|x6E|x6A|x5B|x6B|x5D|x3B|_0xd4b0x6|x20|x3D|x75|x76|x77|x71|x44|x45|x46|x28|x29|String|if|while|45|var|x79|x7A|x41|x2C|x42|x47|x48|x49|x5F|x2B|eval|parseInt|35|29|toString|36|new|RegExp'.split('|'), 0, {
}))
}
I ran it in JSBeautifier and got
function divulge() {
var _0x6159 = ["\x6E\x20\x6A\x3D\x5B\x22\x5C\x75\x5C\x6B\x5C\x66\x5C\x38\x5C\x34\x5C\x76\x5C\x6F\x5C\x64\x5C\x70\x5C\x65\x5C\x66\x5C\x63\x5C\x64\x5C\x34\x5C\x38\x5C\x65\x5C\x63\x5C\x39\x5C\x36\x5C\x38\x5C\x34\x5C\x38\x5C\x63\x5C\x6C\x5C\x36\x5C\x34\x5C\x38\x5C\x36\x5C\x70\x5C\x39\x5C\x36\x5C\x65\x5C\x34\x5C\x6F\x5C\x64\x5C\x77\x5C\x36\x5C\x39\x5C\x34\x5C\x38\x5C\x63\x5C\x6C\x5C\x36\x5C\x34\x5C\x61\x5C\x39\x5C\x71\x5C\x66\x5C\x65\x5C\x39\x5C\x61\x5C\x39\x5C\x78\x5C\x34\x5C\x72\x5C\x61\x5C\x39\x5C\x66\x5C\x61\x5C\x71\x5C\x67\x5C\x36\x5C\x34\x5C\x79\x5C\x6B\x5C\x63\x5C\x38\x5C\x36\x5C\x34\x5C\x64\x5C\x61\x5C\x6C\x5C\x36\x5C\x34\x5C\x7A\x5C\x34\x5C\x38\x5C\x6B\x5C\x61\x5C\x67\x5C\x67\x5C\x34\x5C\x64\x5C\x63\x5C\x65\x5C\x34\x5C\x39\x5C\x36\x5C\x72\x5C\x36\x5C\x61\x5C\x67\x5C\x41\x22\x2C\x22\x5C\x32\x5C\x33\x5C\x42\x5C\x32\x5C\x35\x5C\x6D\x5C\x32\x5C\x35\x5C\x6D\x5C\x32\x5C\x35\x5C\x43\x5C\x32\x5C\x37\x5C\x44\x5C\x32\x5C\x62\x5C\x68\x5C\x32\x5C\x62\x5C\x68\x5C\x32\x5C\x35\x5C\x37\x5C\x32\x5C\x33\x5C\x73\x5C\x32\x5C\x33\x5C\x35\x5C\x32\x5C\x33\x5C\x69\x5C\x32\x5C\x33\x5C\x73\x5C\x32\x5C\x33\x5C\x69\x5C\x32\x5C\x62\x5C\x69\x5C\x32\x5C\x33\x5C\x37\x5C\x32\x5C\x33\x5C\x45\x5C\x32\x5C\x33\x5C\x46\x5C\x32\x5C\x35\x5C\x37\x5C\x32\x5C\x33\x5C\x37\x5C\x32\x5C\x35\x5C\x37\x5C\x32\x5C\x33\x5C\x37\x5C\x32\x5C\x62\x5C\x69\x5C\x32\x5C\x33\x5C\x68\x5C\x32\x5C\x35\x5C\x62\x5C\x32\x5C\x33\x5C\x35\x5C\x32\x5C\x62\x5C\x68\x5C\x32\x5C\x35\x5C\x37\x5C\x32\x5C\x33\x5C\x74\x5C\x32\x5C\x33\x5C\x37\x5C\x32\x5C\x35\x5C\x62\x5C\x32\x5C\x33\x5C\x74\x5C\x32\x5C\x35\x5C\x6D\x5C\x32\x5C\x35\x5C\x37\x22\x5D\x3B\x47\x28\x6A\x5B\x30\x5D\x29\x3B\x6E\x20\x48\x3D\x49\x28\x6A\x5B\x31\x5D\x29\x3B", "\x7C", "\x73\x70\x6C\x69\x74", "\x7C\x7C\x78\x32\x35\x7C\x78\x33\x36\x7C\x78\x32\x30\x7C\x78\x33\x37\x7C\x78\x36\x35\x7C\x78\x33\x33\x7C\x78\x37\x33\x7C\x78\x37\x32\x7C\x78\x36\x31\x7C\x78\x33\x32\x7C\x78\x36\x46\x7C\x78\x36\x45\x7C\x78\x37\x34\x7C\x78\x36\x39\x7C\x78\x36\x43\x7C\x78\x34\x36\x7C\x78\x34\x35\x7C\x5F\x30\x78\x32\x63\x36\x66\x7C\x78\x36\x38\x7C\x78\x36\x44\x7C\x78\x33\x34\x7C\x76\x61\x72\x7C\x78\x37\x35\x7C\x78\x36\x33\x7C\x78\x36\x32\x7C\x78\x37\x36\x7C\x78\x33\x39\x7C\x78\x33\x35\x7C\x78\x35\x34\x7C\x78\x36\x36\x7C\x78\x36\x34\x7C\x78\x37\x39\x7C\x78\x37\x37\x7C\x78\x34\x39\x7C\x78\x32\x31\x7C\x78\x33\x38\x7C\x78\x33\x30\x7C\x78\x34\x31\x7C\x78\x33\x31\x7C\x78\x34\x34\x7C\x61\x6C\x65\x72\x74\x7C\x73\x65\x63\x72\x65\x74\x6F\x73\x7C\x75\x6E\x65\x73\x63\x61\x70\x65", "", "\x66\x72\x6F\x6D\x43\x68\x61\x72\x43\x6F\x64\x65", "\x72\x65\x70\x6C\x61\x63\x65", "\x5C\x77\x2B", "\x5C\x62", "\x67"];
eval(function (_0xd4b0x1, _0xd4b0x2, _0xd4b0x3, _0xd4b0x4, _0xd4b0x5, _0xd4b0x6) {
_0xd4b0x5 = function (_0xd4b0x3) {
return (_0xd4b0x3 < _0xd4b0x2 ? _0x6159[4] : _0xd4b0x5(parseInt(_0xd4b0x3 / _0xd4b0x2))) + ((_0xd4b0x3 = _0xd4b0x3 % _0xd4b0x2) > 35 ? String[_0x6159[5]](_0xd4b0x3 + 29) : _0xd4b0x3.toString(36))
};
if (!_0x6159[4][_0x6159[6]](/^/, String)) {
while (_0xd4b0x3--) {
_0xd4b0x6[_0xd4b0x5(_0xd4b0x3)] = _0xd4b0x4[_0xd4b0x3] || _0xd4b0x5(_0xd4b0x3)
};
_0xd4b0x4 = [
function (_0xd4b0x5) {
return _0xd4b0x6[_0xd4b0x5]
}];
_0xd4b0x5 = function () {
return _0x6159[7]
};
_0xd4b0x3 = 1
};
while (_0xd4b0x3--) {
if (_0xd4b0x4[_0xd4b0x3]) {
_0xd4b0x1 = _0xd4b0x1[_0x6159[6]](new RegExp(_0x6159[8] + _0xd4b0x5(_0xd4b0x3) + _0x6159[8], _0x6159[9]), _0xd4b0x4[_0xd4b0x3])
}
};
return _0xd4b0x1
}(_0x6159[0], 45, 45, _0x6159[3][_0x6159[2]](_0x6159[1]), 0, {}));
}
I'm pretty lost at this point. Is the first code not obfuscated? I don't have much experience in programming, it's a part of a computer science challenge I've been trying to do. I also tried replacing function in line 1 with alert and it said there's a missing semicolon but I'm not sure where.
Here's a quick tutorial on deobfuscating it. I will not go into too much detail because this was a challenge you are supposed to solve afterall.
Take the original code and look at its structure. It basically is of the form
function divulge() {
eval(function(...) {
/* nobody cares what happens here */
// now this is interesting, because p will contain the string that eval() will execute!
return p;
}(...));
}
It should be fairly obvious now how to learn what this code will execute rather than having it actually execute: p will get evaled, so just intercept it. This will show that it's just more code (obviously).
So let's start over! Looking at the new code, after beautifying it, we will see that the structure is basically the same. So someone is trying to be sneaky by obfuscating the code several times. Too bad we already deobfuscated it once, so we just repeat the entire procedure.
After the second time, we get code of the structure
var _0x2c6f = ["..."];
alert(_0x2c6f[0]);
var secretos = unescape(_0x2c6f[1]);
This will alert the following text:
This function stores some secret under some arbitrary variable whose name I shall not reveal!
And finally, secretos contains a link. However, I will censor the link here for multiple reasons:
http://signin.**********.org/secrets
Related
I want to make a chess puzzle on my website for my student.
I use stockfish.js to play with the engine.
How to change the start position on the board?
I try to change all FEN string but did not work.
Where to look for the function or something?
Anybody can help me, please?
Interacting with the javascript port of Stockfish is (at time of writing) still like communicating with a chess engine that uses/supports UCI (Universal Chess Interface).
The UCI position command should suffice:
var fenString = "rnbqkbnr/ppppp1pp/8/5p2/3P4/8/PPP1PPPP/RNBQKBNR w KQkq - 0 2"
// start UCI
stockfish.postMessage("uci");
// start new game
stockfish.postMessage("ucinewgame");
// set new game position
stockfish.postMessage("position fen " + fenString);
// start search
stockfish.postMessage("go depth 10");
Edited: Updated case for postMessage() function.
I was working on the same thing and figured it out -- it's by no means obvious and within the stockfish example there are lots of little trips and pitfalls. I found a couple questions online and thought I'd give them some answers.
So -- this answer assumes working with the example code found here: https://github.com/nmrugg/stockfish.js/tree/Stockfish11/example.
There are two major modifications that need to happen - first in the index.html file and second in enginegame.js.
First we'll define a helper function which will make it easy to work with the url "search" as it's called:
function searchToObject() {
var pairs = window.location.search.substring(1).split("&"),
obj = {},
pair,
i;
for ( i in pairs ) {
if ( pairs[i] === "" ) continue;
pair = pairs[i].split("=");
obj[ decodeURIComponent( pair[0] ) ] = decodeURIComponent( pair[1] );
}
return obj;
}
For ease I just placed that function in both files, within index.html it's at the beginning of the script tag, in enginegame.js it's the very first line. Also btw, I certainly pilfered that from stackoverflow, but I can't seem to find that answer any more, rats.
In index.html the newGame function wants to look like this:
newGame = function newGame() {
var baseTime = parseFloat($('#timeBase').val()) * 60;
var inc = parseFloat($('#timeInc').val());
var skill = parseInt($('#skillLevel').val());
game.reset();
let search = searchToObject();
if (search.player) {
game.setPlayerColor(search.player)
} else {
game.setPlayerColor($('#color-white').hasClass('active') ? 'white' : 'black');
}
if (search.fen) {
game.game.load(search.fen);
game.board.position(game.game.fen());
}
game.setTime(baseTime, inc);
game.setSkillLevel(skill);
game.setDisplayScore($('#showScore').is(':checked'));
game.start();
}
Note the game.game and game.board -- those need to be added in enginegame.js where it's returning an object. If I were writing this I would have done it differently, but I didn't have the patience to rename things.
Next up in enginegame.js we need to adjust prepareMove.
function prepareMove() {
stopClock();
$('#pgn').text(game.pgn());
board.position(game.fen());
updateClock();
var turn = game.turn() == 'w' ? 'white' : 'black';
if (!game.game_over()) {
if (turn != playerColor) {
let search = searchToObject();
if (search.fen) {
uciCmd('position fen ' + search.fen + ' moves ' + get_moves());
} else {
uciCmd('position startpos moves' + get_moves());
uciCmd('position startpos moves' + get_moves(), evaler);
}
evaluation_el.textContent = "";
uciCmd("eval", evaler);
if (time && time.wtime) {
uciCmd("go " + (time.depth ? "depth " + time.depth : "") + " wtime " + time.wtime + " winc " + time.winc + " btime " + time.btime + " binc " + time.binc);
} else {
uciCmd("go " + (time.depth ? "depth " + time.depth : ""));
}
isEngineRunning = true;
}
if (game.history().length >= 2 && !time.depth && !time.nodes) {
startClock();
}
}
}
See, the trick is that if ever there was a fen string to start the game, every subsequent position call needs to be different. I think that's probably what's tripping most people up - that's definitely what got me.
What helped things click for me was reading through the UCI documentation. Before that my board was in some crazy infinite loop.
Also one weird but critical bit I stumbled onto was the game.game.load(<fen string>) function call in the index.html file. I can't find any documentation for that. I don't even remember how I found it. But there it is!
I am trying to create questionnaire (15 questions)in my Messenger with the two possible answers Yes and No. Each answer has value (Yes..3) and (No..1). I create Zap where I calculate number like result. I create Java script code by Zapier like next step and here my knowledge is finished. I code to calculate number and like next step sending the message back with answer like number.
What I want from javascript code by Zapier is to calculate answers and based on the results send the answer to Subscriber who answer the Questionnaire.
The answer message according to the scoring answers should be following:
<26
"messege"
26-35
"messege"
>35
"messege"
Here it is how I made until now (sorry but answers are in Slovene language...not important):
return {
calculatednumber: Number(inputData.q1) + Number(inputData.q2) + Number(inputData.q3) + Number(inputData.q4) + Number(inputData.q5) + Number(inputData.q6) + Number(inputData.q7) + Number(inputData.q8) + Number(inputData.q9) + Number(inputData.q10) + Number(inputData.q11) + Number(inputData.q12) + Number(inputData.q13) + Number(inputData.q14) + Number(inputData.q15)
}
if (calculatednumber ==='<25') {
return []; //"Videti je, da so vaše prehranske navade ustrezne. Za izboljšanje priporočamo jemanje multivitaminskih/mineralnih tablet!"
}
if (calculatednumber ==='26,27,28,29,30,31,32,33,34,35') {
return []; //"Multivitaminski/mineralni dodatek k prehrani bo vašemu telesu pomagal ohraniti esencialna hranila, ki jih potrebuje, skupaj z drugimi označenimi dodatki!"
}
if (calculatednumber ==='>36') {
return []; //"Vnos multivitaminov/mineralov bi vam zagotovo koristil. Z bolj uravnoteženo prehrano in dodatkom multivitaminov/mineralov pa bi potrebovali še vnos drugih vitaminov/mineralov!"
};
Thank you for helping me.
You're on the right track! Some pointers:
You'll only ever call one return function, so you don't want to use it for the variable at the top.
You don't need to nest the variable inside an object; it can just be a number
the calculatedNumber variable will never be equal to "<25" because that's a string with a character in it, so your logic branches don't work.
Try this instead:
let calculatedNumber = Number(inputData.q1) + Number(inputData.q2) // + ...
if (calculatedNumber < 25) {
return {message: 'Small Message'} // it's important to return an object
} else if (calculatedNumber > 36) {
return {message: 'Large Message'}
} else {
// everything inbetween 25 and 36
return {message: 'Medium Message'}
}
Anyway, I'd recommend reading through https://learnxinyminutes.com/docs/javascript/ to get a better handle on some of the syntax fundamentals.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I am making an Encryption Tool for myself, being a code of JavaScript, inserted into the console( interpreter ) and run, doing what follows( The code is NOT 100% JavaScript, it is an imaginary code that refers to what I want in real JavaScript ):
var encrypt_f = function(z) {
switch(z) {
case "H":
return "0XB";
break;
case "e":
return "EWD";
break;
case "l":
return "FXB";
break;
case "o":
return "#RS";
break;
default:
return "UNK";
break;
} // I will write the rest of words, I got my encryption table
}
var encrypt = function(x) {
// Turn x into an array
// Then make a for loop, to check for every element in the array
// and scan the letter, then, Encrypt the letter, I've provided
// "Hello" as a word to Encrypt, I'll do the rest
// as of:
// var enc = "";
// for(.. i ..) { y = x[i]; enc += encrypt_f(y) + " ";
}
encrypt("Hello");
The encrypt("Hello"); should return 0XB EWD FXB FXB #RS as:
0XB being H
EWD being e
FXB being l - Being wrote twice as there are 2 l's in Hello
#RS being o
NOTE: ONLY JAVASCRIPT, I want the code to be inserted into the browser console to return a string and NOT for sending data to databases or anything like that, the code is NOT written into the script tag, but being inserted into a browser, also, if you can, please make the code plain JavaScript without any external libraries( jQuery )
Just iterate over the string (here with a split of the string and then over the array and with map and the encoding ad callback. The result array is then joined with a space).
var encrypt_f = function (z) {
return { H: '0XB', e: 'EWD', l: 'FXB', o: '#RS' }[z] || 'UNK';
},
encrypt = function (x) {
return x.split('').map(encrypt_f).join(' ');
};
document.write(encrypt("Hello!"));
to map a string to another you can abuse replace()
var mapping = {
"H": "0XB",
"e": "EWD",
"l": "FXB",
"o": "#RS",
default: "UNK"
};
function encrypt(mapping, string){
return string.replace(/[\s\S]/g, function(chr){
//binding and accessing this is faster than a closure
return this[chr] || this.default;
}.bind(mapping));
}
encrypt(mapping, "Hello")
This should work. Jsbin: https://jsbin.com/yiborehuju/edit?js,output
var encrypt = function(x) {
var enc = "";
x = x.split('');
x.forEach(function(l) {
e = encrypt_f(l);
enc += e;
});
return enc;
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have a collection (of about 61000) strings that look like
"(((((((((.(((((.&.)))))))))))))) 11,26 : 6,20 (-9.37 = -16.05 + 6.56 + 0.13) GCCAACUGACGUUGUU&AAUAAUUCAGUUGGU"
There are a variable number of spaces (1-3) between each part of the string.
Ultimately what I want is to convert this string to a javascript object:
{
parens: "(((((((((.(((((.&.))))))))))))))",
sRNAstart: 11,
sRNAend: 26,
mRNAstart: 6,
mRNAend: 20,
netEnergy: -9.37,
bindingEnergy: -16.05,
sRNAOpenEnergy: 6.56,
mRNAOpenEnergy: 0.13,
sequences: "GCCAACUGACGUUGUU&AAUAAUUCAGUUGGU"
}
This sounds like a job for RegEx man, bust sadly I am not him. Can anyone help me figure out a way to accomplish this?
here is a way to use regexp to parse the string, with one internal work-around for those pesky parens:
var s="(((((((((.(((((.&.)))))))))))))) 11,26 : 6,20 (-9.37 = -16.05 + 6.56 + 0.13) GCCAACUGACGUUGUU&AAUAAUUCAGUUGGU";
var ob=s.split( /([\s]{1,4}|[,=+:()])/ )
.filter( /./.test, /\w/ )
.map(function(chunk, i){
if(i===0) this.parens= s.split(" ")[0];
this[[ "sRNAstart","sRNAend","mRNAstart","mRNAend","netEnergy",
"bindingEnergy","sRNAOpenEnergy","mRNAOpenEnergy","sequences"
][i]]= +chunk || (chunk==="0"? 0 : chunk);
return this;
},{})[0] ; //end ob
alert(
JSON.stringify(
ob,
null,
"\t"
)
);
result:
{
"parens": "(((((((((.(((((.&.))))))))))))))",
"sRNAstart": 11,
"sRNAend": 26,
"mRNAstart": 6,
"mRNAend": 20,
"netEnergy": -9.37,
"bindingEnergy": -16.05,
"sRNAOpenEnergy": 6.56,
"mRNAOpenEnergy": 0.13,
"sequences": "GCCAACUGACGUUGUU&AAUAAUUCAGUUGGU"
}
EDIT: removed use of non-capturing parens for more x-browser compat with OLD browsers.
EDIT: adjustments: make "0" into 0, avoid setting this.parens each time, formatting, and argument cleanup.
A Javascript split() with multiple delimiters should yield an array of all of the values you need.
From there, it's simple string concatenation.
This expression will not ensure that the parentheses are matched, but it should break out everything in your pattern.
([(.&)]+)\s*(\d+),(\d+)\s*:\s*(\d+),(\d+)\s*\(([-.\d]+)\s*=\s*([-.\d]+)\s*\+\s*([-.\d]+)\s*\+\s*([-.\d]+)\)\s*([GCAU&]+)
Here is an alternative that should also work for you and is cross-browser.
Javascript
function parse(string) {
if (typeof string !== "string") {
throw new TypeError("Attribute must be a string.");
}
var props = ["parens", "sRNAstart", "sRNAend", "mRNAstart", "mRNAend", "netEnergy", "bindingEnergy", "sRNAOpenEnergy", "mRNAOpenEnergy", "sequences"],
array = string.split(/[)]?\s+[(:=+]?\s*|,/),
object = {},
value;
if (array.length !== props.length) {
throw new Error("String could not be converted.");
}
do {
value = array.shift();
object[props.shift()] = +value || value;
} while (props.length);
return object;
}
var ref = "(((((((((.(((((.&.)))))))))))))) 11,26 : 6,20 (-9.37 = -16.05 + 6.56 + 0.13) vGCCAACUGACGUUGUU&AAUAAUUCAGUUGGU";
for(var i = 0; i < 3; i += 1) {
console.log(ref, parse(ref));
ref = ref.replace(/(\s+)/g, function (all, whitespace) {
return whitespace + " ";
});
}
On jsfiddle
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I have seen "https://stackoverflow.com/questions/1385335/how-to-generate-function-call-graphs-for-javascript", and tried it. It works well, if you want to get an abstract syntax tree.
Unfortunately Closure Compiler only seems to offer --print_tree, --print_ast and --print_pass_graph. None of them are useful for me.
I want to see a chart of which function calls which other functions.
code2flow does exactly this. Full disclosure, I started this project
To run
$ code2flow source1.js source2.js -o out.gv
Then, open out.gv with graphviz
Edit: For now, this project is unmaintained. I would suggest trying out a different solution before using code2flow.
If you filter the output of closure --print_tree you get what you want.
For example take the following file:
var fib = function(n) {
if (n < 2) {
return n;
} else {
return fib(n - 1) + fib(n - 2);
}
};
console.log(fib(fib(5)));
Filter the output of closure --print_tree
NAME fib 1
FUNCTION 1
CALL 5
NAME fib 5
SUB 5
NAME a 5
NUMBER 1.0 5
CALL 5
NAME fib 5
SUB 5
NAME a 5
NUMBER 2.0 5
EXPR_RESULT 9
CALL 9
GETPROP 9
NAME console 9
STRING log 9
CALL 9
CALL 9
NAME fib 9
CALL 9
CALL 9
NAME fib 9
NUMBER 5.0 9
And you can see all the call statements.
I wrote the following scripts to do this.
./call_tree
#! /usr/bin/env sh
function make_tree() {
closure --print_tree $1 | grep $1
}
function parse_tree() {
gawk -f parse_tree.awk
}
if [[ "$1" = "--tree" ]]; then
make_tree $2
else
make_tree $1 | parse_tree
fi
parse_tree.awk
BEGIN {
lines_c = 0
indent_width = 4
indent_offset = 0
string_offset = ""
calling = 0
call_indent = 0
}
{
sub(/\[source_file.*$/, "")
sub(/\[free_call.*$/, "")
}
/SCRIPT/ {
indent_offset = calculate_indent($0)
root_indent = indent_offset - 1
}
/FUNCTION/ {
pl = get_previous_line()
if (calculate_indent(pl) < calculate_indent($0))
print pl
print
}
{
lines_v[lines_c] = $0
lines_c += 1
}
{
indent = calculate_indent($0)
if (indent <= call_indent) {
calling = 0
}
if (calling) {
print
}
}
/CALL/ {
calling = 1
call_indent = calculate_indent($0)
print
}
/EXPR/{
line_indent = calculate_indent($0)
if (line_indent == root_indent) {
if ($0 !~ /(FUNCTION)/) {
print
}
}
}
function calculate_indent(line) {
match(line, /^ */)
return int(RLENGTH / indent_width) - indent_offset
}
function get_previous_line() {
return lines_v[lines_c - 1]
}
I finally managed this using UglifyJS2 and Dot/GraphViz, in a sort of combination of the above answer and the answers to the linked question.
The missing part, for me, was how to filter the parsed AST. It turns out that UglifyJS has the TreeWalker object, which basically applys a function to each node of the AST. This is the code I have so far:
//to be run using nodejs
var UglifyJS = require('uglify-js')
var fs = require('fs');
var util = require('util');
var file = 'path/to/file...';
//read in the code
var code = fs.readFileSync(file, "utf8");
//parse it to AST
var toplevel = UglifyJS.parse(code);
//open the output DOT file
var out = fs.openSync('path/to/output/file...', 'w');
//output the start of a directed graph in DOT notation
fs.writeSync(out, 'digraph test{\n');
//use a tree walker to examine each node
var walker = new UglifyJS.TreeWalker(function(node){
//check for function calls
if (node instanceof UglifyJS.AST_Call) {
if(node.expression.name !== undefined)
{
//find where the calling function is defined
var p = walker.find_parent(UglifyJS.AST_Defun);
if(p !== undefined)
{
//filter out unneccessary stuff, eg calls to external libraries or constructors
if(node.expression.name == "$" || node.expression.name == "Number" || node.expression.name =="Date")
{
//NOTE: $ is from jquery, and causes problems if it's in the DOT file.
//It's also very frequent, so even replacing it with a safe string
//results in a very cluttered graph
}
else
{
fs.writeSync(out, p.name.name);
fs.writeSync(out, " -> ");
fs.writeSync(out, node.expression.name);
fs.writeSync(out, "\n");
}
}
else
{
//it's a top level function
fs.writeSync(out, node.expression.name);
fs.writeSync(out, "\n");
}
}
}
if(node instanceof UglifyJS.AST_Defun)
{
//defined but not called
fs.writeSync(out, node.name.name);
fs.writeSync(out, "\n");
}
});
//analyse the AST
toplevel.walk(walker);
//finally, write out the closing bracket
fs.writeSync(out, '}');
I run it with node, and then put the output through
dot -Tpng -o graph_name.png dot_file_name.dot
Notes:
It gives a pretty basic graph - only black and white and no formatting.
It doesn't catch ajax at all, and presumably not stuff like eval or with either, as others have mentioned.
Also, as it stands it includes in the graph: functions called by other functions (and consequently functions that call other functions), functions that are called independantly, AND functions that are defined but not called.
As a result of all this, it may miss things that are relevant, or include things that are not. It's a start though, and appears to accomplish what I was after, and what led me to this question in the first place.
https://github.com/mishoo/UglifyJS
gives access to an ast in javascript.
ast.coffee
util = require 'util'
jsp = require('uglify-js').parser
orig_code = """
var a = function (x) {
return x * x;
};
function b (x) {
return a(x)
}
console.log(a(5));
console.log(b(5));
"""
ast = jsp.parse(orig_code)
console.log util.inspect ast, true, null, true