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
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
So I am creating a "Silly Story Generator" in Javascript and after fixing a few errors that popped up I encountered "SyntaxError: missing ) after argument list"
After reading more about it I learned that it occurs when there is an error with how a function is called. This might be a typo, a missing operator, or an unescaped string.
I checked my code and I cannot seem to find the mistake, string on line 38 looks okay.
Thank you.
randomize.addEventListener('click', result);
function result() {
if (customName.value !== '') {
let name = customName.value;
}
if (document.getElementById("uk").checked) {
let weight = Math.round(300);
let temperature = Math.round(94);
}
story.text = ""
story.style.visbility = 'visible';
var newStory = storyText;
let xItem = randomValueFromArray;
let yItem = randomValueFromArray;
let zItem = randomValueFromArray;
function newStory(buttonPress) {
newStory.contentString.replace("insertX", "insertY", "insertZ")
content.contentString.replace("xItem ", "yItem", "zItem");
}
}
Your Code is Badly formatted.
At newStory.contentString.replace("insertX", "insertY", "insertZ";)
You had a semi-colon inside the the parenthesis.
You are also missing two curly braces near the end.
I suggest getting a good IDE or using the formatting features that come with the one you use.
randomize.addEventListener('click', result);
function result() {
if (customName.value !== '') {
let name = customName.value;
}
if (document.getElementById("uk").checked) {
let weight = Math.round(300);
let temperature = Math.round(94);
}
story.text = ""
story.style.visbility = 'visible';
var newStory = storyText;
let xItem = randomValueFromArray;
let yItem = randomValueFromArray;
let zItem = randomValueFromArray;
function newStory(buttonPress) {
newStory.contentString.replace("insertX", "insertY", "insertZ")
content.contentString.replace("xItem ", "yItem", "zItem");
}
}
you have written a semicolon before the closing parentheses
newStory.contentString.replace("insertX", "insertY", "insertZ");
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
I'm trying to modify an element in jQuery programmatically, i.e. a number in docID increments up to a maximum number. I'm replacing text on a series of images on a page from Download to View. If I use #ctl00_cphMainContent_dlProductList_ct100_ctl00_lnkProofDownload instead of docID in the $(docID).text(...) part of the code, the text gets replaced correctly. When I use the docID variable in its place, it doesn't work.
What am I doing wrong here?
Thanks.
var max = 10;
var count = 100;
var s1 = "#ctl00_cphMainContent_dlProductList_ct";
var s2 = "_ctl00_lnkProofDownload";
var docID = "";
for (i = 1; i <= max; i++)
{
docID = s1.concat (count++, s2);
$(document).ready(function() {
$(docID).text(function(i, oldText) {
return oldText === 'Download' ? 'View' : oldText;
});
});
}
This is the HTML code that is being modified. The word Download is replaced by View.
<a id="ctl00_cphMainContent_dlProductList_ctl00_ctl00_lnkProofDownload"
href="../../../Controls/StaticDocProof.ashx?qs=op/5WlcUxeg849UT973Mwf0ZnNcMLfe3JYAe7EnJORsdyETYV1vcKaj0ROc2VrN5fXfYjO2MM6BUYXzX2UKmog=="
>Download</a>
It looks like you have done a couple things incorrectly in your code, including using a 1 instead of an l. If it was supposed to be a 100 instead of a l00, something more like this would work:
jQuery(function () {
var max = 10,
count = 100,
s1 = 'ctl00_cphMainContent_dlProductList_ct',
s2 = '_ctl00_lnkProofDownload',
docID;
for (var i = count; i <= count + max; i++) {
docID = s1 + i + s2;
jQuery('#' + docID).text(function (idx, oldText) {
return oldText === 'Download' ? 'View' : oldText;
});
}
});
Fiddle here: http://jsfiddle.net/ochguL2d/
Otherwise, let us know if it is supposed to be l00 for a different answer.
Your a element has this in the middle (note two "els"):
ctl00_ctl00
… but your docID has this in the middle (note a "one and an el"):
ct100_ctl00
Fix your HTML, and your code works as-is: http://jsfiddle.net/5c7hwyts/
However, that's an odd way to write jQuery.
Here's a different approach:
$('a').text(function(i, oldText) {
var num= parseInt(this.id.split('ctl00_cphMainContent_dlProductList_ct')[1]);
if(num>=100 && num<110) {
return oldText === 'Download' ? 'View' : oldText;
}
});
Fiddle
The element IDs your are trying to match in your code are not the ones in the DOM.
// This is what you want to match
var domID = "#ctl00_cphMainContent_dlProductList_ct100_ctl00_lnkProofDownload"
^ that is an L
// this what your code is trying to match in its first iteration
var docID = "#ctl00_cphMainContent_dlProductList_ct10_ctl00_lnkProofDownload";"
^ that is a 1 (one)
Also, your code's max variable needs to be a two char numeric string with leading zeros starting at zero, not an integer starting at 10.
Personally, I would just:
// On DomReady...
$(document).ready(function() {
// loop through all anchors that have "lnkProofDownload" in their ID attribute
$('a[id*="lnkProofDownload"]').each(function() {
// and if the text is set to "Download", change it to "View"
if ($(this).text() == "Download") {
$(this).text("View");
}
});
});
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
My question is similar to THIS question that hasn't been answered yet.
How can I make my code (or any javascript code that might be suggested?) find all possible solutions of a known string length with multiple missing characters in variation with repetition?
I'm trying to take a string of known character lengths and find missing characters from that string. For example:
var missing_string = "ov!rf!ow"; //where "!" are the missing characters
I'm hoping to run a script with a specific array such as:
var r = new Array("A","B","C","D","E","F","G","H","I","J","K",
"L","M","N","O","P","Q","R","S","T","U","V",
"W","X","Y","Z",0,1,2,3,4,5,6,7,8,9);
To find all the possible variations with repetition of those missing characters to get a result of:
ovArfAow
ovBrfAow
ovCrfAow
...
ovBrfBow
ovBrfCow
...
etc //ignore the case insensitive, just to emphasize the example
and of course, eventually find ovErfLow within all the variations with repetition.
I've been able to make it work with 1 (single) missing character. However, when I put 2 missing characters with my code it obviously repeats the same array character for both missing characters which is GREAT for repition but I also need to find without repetition as well and might need to have 3-4 missing characters as well which may or may not be repeated. Here's what I have so far:
var r = new Array("A","B","C","D","E","F","G","H","I","J","K",
"L","M","N","O","P","Q","R","S","T","U","V",
"W","X","Y","Z",0,1,2,3,4,5,6,7,8,9);
var missing_string = "he!!ow!r!d";
var bt_lng = missing_string.length;
var bruted="";
for (z=0; z<r.length; z++) {
for(var x=0;x<bt_lng;x++){
for(var y=0;y<r.length;y++){
if(missing_string.charAt(x) == "!"){
bruted += r[z];
break;
}
else if(missing_string.charAt(x) == r[y]){
bruted += r[y];
}
}
}
console.log("br: " + bruted);
bruted="";
}
This works GREAT with just ONE "!":
helloworAd
helloworBd
helloworCd
...
helloworLd
However with 2 or more "!", I get:
heAAowArAd
heBBowBrBd
heCCowCrCd
...
heLLowLrLd
which is good for the repetition part but I also need to test all possible array M characters in each missing character spot.
Maybe the following function in pure javascript is a possible solution for you. It uses Array.prototype.reduce to create the cartesian product c of the given alphabet x, whereby its power n depends on the count of the exclamation marks in your word w.
function combinations(w) {
var x = new Array(
"A","B","C","D","E","F","G","H","I","J","K",
"L","M","N","O","P","Q","R","S","T","U","V",
"W","X","Y","Z",0,1,2,3,4,5,6,7,8,9
),
n = w.match(/\!/g).length,
x_n = new Array(),
r = new Array(),
c = null;
for (var i = n; i > 0; i--) {
x_n.push(x);
}
c = x_n.reduce(function(a, b) {
var c = [];
a.forEach(function(a) {
b.forEach(function(b) {
c.push(a.concat([b]));
});
});
return c;
}, [[]]);
for (var i = 0, j = 0; i < c.length; i++, j = 0) {
r.push(w.replace(/\!/g, function(s, k) {
return c[i][j++];
}));
}
return r;
}
Call it like this console.log(combinations("ov!rf!ow")) in your browser console.
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