Most effecient way to solve a formula in javascript - javascript
Say I have the following formula
a + (13 * (b/c)) + d + (12 * e) - f - 11 + (g * (h/i)) - 10 = 66;
Now the letters a-i can represent a number from 1-9. However, each number can only be used once. What would be the most efficient way to solve this? The way I have at the moment is to generate an array of random numbers e.g.
array[2,5,1,7,8,6,9,3,4]
I then fit this into the formula to check if it equals 66. If not, I generate a new array of numbers. I was thinking there should be a better way to do this though, maybe using recursion?
Just wanted to get some input in how you would tackle this?
Thanks
I think there's no smarter algorithm than just trying with each permutation of the numbers in the set for equality. Which I think will be easier for you, than creating everytime an unique array, that was not already generated.
In the code bellow I have used very primitive check for equality between numbers. There might be an easier way from the standard javascript library (e.g. if number is found in the predefined set...)
var solutions = [];
for (var a = 1; a <= 9; a++) {
for (var b = 1; b <= 9; b++) {
if ( b == a ) continue;
for (var c = 1; c <= 9; c++) {
if ( c == b || c == a ) continue;
for (var d = 1; d <= 9; d++) {
if ( d == c || d == b || d == a ) continue;
for (var e = 1; e <= 9; e++) {
if ( e == d || e == c || e == b || e == a ) continue;
for (var f = 1; f <= 9; f++) {
if ( f == e || f == d || f == c || f == b || f == a ) continue;
for (var g = 1; g <= 9; g++) {
if ( g == f || g == e || g == d || g == c || g == b || g == a ) continue;
for (var h = 1; h <= 9; h++) {
if ( h == g || h == f || h == e || h == d || h == c || h == b || h == a ) continue;
for (var i = 1; i <= 9; i++) {
if ( i == h || i == g || i == f || i == e || i == d || i == c || i == b || i == a ) continue;
if ((a + (13 * (b/c)) + d + (12 * e) - f - 11 + (g * (h/i)) - 10) == 66) {
solutions.push(a + "," + b + "," + c + "," + d + "," + e + "," + f + "," + g + "," + h + "," + i);
}
}
}
}
}
}
}
}
}
}
console.log(solutions);
Which results into a lot of solutions
["1,2,6,4,7,8,3,5,9", "1,2,6,4,7,8,5,3,9", "1,3,2,4,5,8,7,9,6", "1,3,2,4,5,8,9,7,6", "1,3,2,9,5,6,4,7,8", "1,3,2,9,5,6,7,4,8", "1,3,4,7,6,5,2,9,8", "1,3,4,7,6,5,9,2,8", "1,3,6,2,7,9,4,5,8", "1,3,6,2,7,9,5,4,8", "1,3,9,4,7,8,2,5,6", "1,3,9,4,7,8,5,2,6", "1,4,8,2,7,9,3,5,6", "1,4,8,2,7,9,5,3,6", "1,5,2,3,4,8,7,9,6", "1,5,2,3,4,8,9,7,6", "1,5,2,8,4,7,3,9,6", "1,5,2,8,4,7,9,3,6", "1,5,3,9,4,2,7,8,6", "1,5,3,9,4,2,8,7,6", "1,9,6,4,5,8,3,7,2", "1,9,6,4,5,8,7,3,2", "1,9,6,7,5,2,3,4,8", "1,9,6,7,5,2,4,3,8", "2,1,4,3,7,9,5,6,8", "2,1,4,3,7,9,6,5,8", "2,3,6,1,7,9,4,5,8", "2,3,6,1,7,9,5,4,8", "2,4,8,1,7,9,3,5,6", "2,4,8,1,7,9,5,3,6", "2,8,6,9,4,1,5,7,3", "2,8,6,9,4,1,7,5,3", "2,9,6,3,5,1,4,7,8", "2,9,6,3,5,1,7,4,8", "3,1,4,2,7,9,5,6,8", "3,1,4,2,7,9,6,5,8", "3,2,1,5,4,7,8,9,6", "3,2,1,5,4,7,9,8,6", "3,2,4,8,5,1,7,9,6", "3,2,4,8,5,1,9,7,6", "3,2,8,6,5,1,7,9,4", "3,2,8,6,5,1,9,7,4", "3,5,2,1,4,8,7,9,6", "3,5,2,1,4,8,9,7,6", "3,6,4,9,5,8,1,7,2", "3,6,4,9,5,8,7,1,2", "3,9,2,8,1,5,6,7,4", "3,9,2,8,1,5,7,6,4", "3,9,6,2,5,1,4,7,8", "3,9,6,2,5,1,7,4,8", "4,2,6,1,7,8,3,5,9", "4,2,6,1,7,8,5,3,9", "4,3,2,1,5,8,7,9,6", "4,3,2,1,5,8,9,7,6", "4,3,9,1,7,8,2,5,6", "4,3,9,1,7,8,5,2,6", "4,9,6,1,5,8,3,7,2", "4,9,6,1,5,8,7,3,2", "5,1,2,9,6,7,3,4,8", "5,1,2,9,6,7,4,3,8", "5,2,1,3,4,7,8,9,6", "5,2,1,3,4,7,9,8,6", "5,3,1,7,2,6,8,9,4", "5,3,1,7,2,6,9,8,4", "5,4,1,9,2,7,3,8,6", "5,4,1,9,2,7,8,3,6", "5,4,8,9,6,7,1,3,2", "5,4,8,9,6,7,3,1,2", "5,7,2,8,3,9,1,6,4", "5,7,2,8,3,9,6,1,4", "5,9,3,6,2,1,7,8,4", "5,9,3,6,2,1,8,7,4", "6,2,8,3,5,1,7,9,4", "6,2,8,3,5,1,9,7,4", "6,3,1,9,2,5,7,8,4", "6,3,1,9,2,5,8,7,4", "6,9,3,5,2,1,7,8,4", "6,9,3,5,2,1,8,7,4", "7,1,4,9,6,5,2,3,8", "7,1,4,9,6,5,3,2,8", "7,2,8,9,6,5,1,3,4", "7,2,8,9,6,5,3,1,4", "7,3,1,5,2,6,8,9,4", "7,3,1,5,2,6,9,8,4", "7,3,2,8,5,9,1,6,4", "7,3,2,8,5,9,6,1,4", "7,3,4,1,6,5,2,9,8", "7,3,4,1,6,5,9,2,8", "7,5,2,8,4,9,1,3,6", "7,5,2,8,4,9,3,1,6", "7,6,4,8,5,9,1,3,2", "7,6,4,8,5,9,3,1,2", "7,9,6,1,5,2,3,4,8", "7,9,6,1,5,2,4,3,8", "8,2,4,3,5,1,7,9,6", "8,2,4,3,5,1,9,7,6", "8,3,2,7,5,9,1,6,4", "8,3,2,7,5,9,6,1,4", "8,5,2,1,4,7,3,9,6", "8,5,2,1,4,7,9,3,6", "8,5,2,7,4,9,1,3,6", "8,5,2,7,4,9,3,1,6", "8,6,4,7,5,9,1,3,2", "8,6,4,7,5,9,3,1,2", "8,7,2,5,3,9,1,6,4", "8,7,2,5,3,9,6,1,4", "8,9,2,3,1,5,6,7,4", "8,9,2,3,1,5,7,6,4", "9,1,2,5,6,7,3,4,8", "9,1,2,5,6,7,4,3,8", "9,1,4,7,6,5,2,3,8", "9,1,4,7,6,5,3,2,8", "9,2,8,7,6,5,1,3,4", "9,2,8,7,6,5,3,1,4", "9,3,1,6,2,5,7,8,4", "9,3,1,6,2,5,8,7,4", "9,3,2,1,5,6,4,7,8", "9,3,2,1,5,6,7,4,8", "9,4,1,5,2,7,3,8,6", "9,4,1,5,2,7,8,3,6", "9,4,8,5,6,7,1,3,2", "9,4,8,5,6,7,3,1,2", "9,5,3,1,4,2,7,8,6", "9,5,3,1,4,2,8,7,6", "9,6,4,3,5,8,1,7,2", "9,6,4,3,5,8,7,1,2", "9,8,6,2,4,1,5,7,3", "9,8,6,2,4,1,7,5,3"]
If the formula is only this, and will not change, you might try to think if there are ranges that are not included in the result set per definition. For example, if you find that some of the numbers cannot be 9, you should not iterate to 9. E.g. the multiplications in the formula might exceed a number that even added to the minimal values in the other variables to exceed 66.
Brute force method:
function findSolution() {
for (var a = 1; a <= 9; a++) {
for (var b = 1; b <= 9; b++) {
for (var c = 1; c <= 9; c++) {
for (var d = 1; d <= 9; d++) {
for (var e = 1; e <= 9; e++) {
for (var f = 1; f <= 9; f++) {
for (var g = 1; g <= 9; g++) {
for (var h = 1; h <= 9; h++) {
for (var i = 1; i <= 9; i++) {
if (
[b,c,d,e,f,g,h,i].indexOf(a) >= 0 ||
[a,c,d,e,f,g,h,i].indexOf(b) >= 0 ||
[a,b,d,e,f,g,h,i].indexOf(c) >= 0 ||
[a,b,c,e,f,g,h,i].indexOf(d) >= 0 ||
[a,b,c,d,f,g,h,i].indexOf(e) >= 0 ||
[a,b,c,d,e,g,h,i].indexOf(f) >= 0 ||
[a,b,c,d,e,f,h,i].indexOf(g) >= 0 ||
[a,b,c,d,e,f,g,i].indexOf(h) >= 0 ||
[a,b,c,d,e,f,g,h].indexOf(i) >= 0
) {
continue;
}
if (a + (13 * (b/c)) + d + (12 * e) - f - 11 + (g * (h/i)) - 10 === 66) {
return [a,b,c,d,e,f,g,h,i];
}
}
}
}
}
}
}
}
}
}
}
document.getElementById('result').innerText = findSolution().join(', ')
<span id="result"></span>
Related
Efficient way to get longest palindrome subsequence in a string
I'm trying to implement a function that takes a string as input and returns the longest palindrome subsequence in the string. I've tried using dynamic programming and have come up with the following code: function longestPalindromicSubsequence(str) { let n = str.length; let dp = Array(n); for (let i = 0; i < n; i++) { dp[i] = Array(n); dp[i][i] = 1; } for (let cl = 2; cl <= n; cl++) { for (let i = 0; i < n - cl + 1; i++) { let j = i + cl - 1; if (str[i] === str[j] && cl === 2) dp[i][j] = 2; else if (str[i] === str[j]) dp[i][j] = dp[i + 1][j - 1] + 2; else dp[i][j] = Math.max(dp[i][j - 1], dp[i + 1][j]); } } return dp[0][n - 1]; } However, this code doesn't seem to be giving me efficient and better results for all test cases. The Time and Space Complexity is also be reduced. I've been struggling with this for days and can't seem to find the issue. Can someone help me figure out what's going wrong and how to fix it?
Oh, I think Dynamic Programming does not work with this sort of problem, because it does not break down recursively, i.e. to find the longest palindrome in a string, you don't need all second-largest palindromes. You can just check at each position and see if it is the center of a palindrome longer than any before. This can be solved with a greedy algorithm: const pals = "asd1234321fghjkl1234567887654321qwertzu1234321" function palindromeAtPos(str, pos, checkEven = false){ let ix = 0 const off = checkEven ? 2 : 1 while(pos-ix-1 >= 0 && pos+ix+1+off < str.length && str[pos-ix-1] === str[pos+ix+off]){ ix++ } return ix === 0 ? str[pos] : str.substring(pos-ix, pos+ix+off) } function longestPalindrome(str){ let longest = '' for(let i = 1; i < str.length; i++){ const odd = palindromeAtPos(str, i) longest = odd.length > longest.length ? odd : longest const even = palindromeAtPos(str, i, true) longest = even.length > longest.length ? even : longest } return longest } console.log(longestPalindrome(pals)) On paper (and for a string like aaaaaaaaaa), this has quadratic complexity, but for most strings, it will be almost linear.
/* * s => string * return [] of strings witch have the max lenth */ function maxLenPalindromes(s) { const l = s.length let c, z, zz, a, b, a1, b1, maxl = 0, result = [] if (l < 2) return result for (c = 0; c < l - 1; c++) { a = -1 if (maxl>(l-c)*2+1) return result if (c > 0 && s[c - 1] == s[c + 1]) { zz = Math.min(c, l - c - 1) for (z = 1; z <= zz; z++) { if (s[c - z] != s[c + z]) { a = c - z + 1; b = c + z break } else if (z == zz) { a = c - z; b = c + z + 1 break } } if (a >= 0) { if (b-a > maxl) { result = [s.slice(a, b)] maxl = b-a } else if (b-a == maxl) { result.push(s.slice(a, b)) } } } a=-1 if (s[c] == s[c + 1]) { if (c == 0 || c == l - 2) { a = c; b = c + 2 } else { zz = Math.min(c, l - c - 2) for (z = 1; z <= zz; z++) { if (s[c - z] != s[c + z + 1]) { a = c - z + 1; b = c + z + 1 break } else if (z == zz) { a = c - z; b = c + z + 2 break } } } if (a >= 0) { if (b-a > maxl) { result = [s.slice(a, b)] maxl = b-a } else if (b-a == maxl) { result.push(s.slice(a, b)) } } } } return result } const s1="112233111222333" const s2="11_22_33_111_222_333" const s3="12345_54321xqazws_swzaq_qwertytrewq" const s4="sdfgsdfg1qqqqqAAAAA_123456789o o987654321_AAAAAqqqqq;lakdjvbafgfhfhfghfh" console.log(maxLenPalindromes(s1)) console.log(maxLenPalindromes(s2)) console.log(maxLenPalindromes(s3)) console.log(maxLenPalindromes(s4))
Need assistance in understanding javascript order of precedence
I'm having an issue understanding how the following statement is working. // setup var n = 3; var J = 3; var g = 0; var p = 41; var m = false; var O = 22; var z = 15; var I = [7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,21,19,20,22,18,20,19,21,7,7,17,17,17,17,17,17,17,17,7,7,0,0,0,0,0,0,0,0,7,7,0,0,0,0,0,0,0,0,7,7,0,0,0,0,0,0,0,0,7,7,0,0,0,0,0,0,0,0,7,7,25,25,25,25,25,25,25,25,7,7,29,27,28,30,26,28,27,29,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,,,22] // statement n += J || (g = p, m = p < O ? g - 3 : g + 2, I[m] < z | I[m + O - p] || I[p += p - O]) ? 1 : 0; At the end of the statement n=4 but I don't understand how or why. I would expect: n += 3 || 1 // n = 6 This is someone else's code I'm trying to understand. Any help is appreciated.
Let's simplify your expression a little. n += X || Y ? 1 : 0 where X = J Y = (g = p, m = p < O ? g - 3 : g + 2, I[m] < z | I[m + O - p] || I[p += p - O]) Here we can see that we are evaluating X || Y and, on the basis of this, the ternary operator ? returns a value of either 1 or 0. Since X || Y evaluates to true, we get n += 1 impliying that n = 4.
It's quite simple. J || (g = p, m = p < O ? g - 3 : g + 2, I[m] < z | I[m + O - p] || I[p += p - O]) ? 1 : 0 This above equals (J || anything) ? 1 : 0. Since J=3, it's like (3 || anything) ? 1 : 0. n += 3 || anything ? 1 : 0 -> n += 1
Number Formatting for large integer numbers in Javascript
I know there are in-build function in javascript like toLocalString() to achieve number formatting. But this question is purely for learning and logic understanding. I have a function in javascript that formats given number in Indian Number formatting standards (eg: 1,234 | 12,21,123 | etc) Code function formatter(input) { var inputStr = input.toString(), l = inputStr.length; var c = 1, f = 0; console.log(l); for (var x=l-1; x>=0; x--) { if (x === 0) { continue; } if (c === 3 && f === 0) { inputStr = inputStr.substring(0, x) + ',' + inputStr.substring(x); f = 1; c = 0; } else if (c % 2 === 0 && f === 1) { inputStr = inputStr.substring(0, x) + ',' + inputStr.substring(x); c = 0; } c++; } return inputStr; } Now this works for most part (as far as I have test, do point out bugs if you spot any). But my question is how do I handle large number in this, i.e. how do I handle values greater than 9007199254740991.
Hope this now fixes the issue: function formatter(inputStr) { inputStr+=""; let c = 1, f = 0; for (let x=inputStr.length-1; x>=0; x--) { if (x === 0) continue; if (c === 3 && f === 0) { inputStr = inputStr.substring(0, x) + ',' + inputStr.substring(x); f = 1; c = 0; } else if (c % 2 === 0 && f === 1) { inputStr = inputStr.substring(0, x) + ',' + inputStr.substring(x); c = 0; } c++; } return inputStr; } //========= Tests ======= console.log(formatter(9007199254740991)); console.log(formatter("900719925474093454549341")); console.log(formatter("123456678890987665443221112345667676766545434243"));
While loop runs forever in JavaScript
I've writen a function in JavaScript that checks through all the combinations of three digits between 1 and 9 and gives me the number of combinations that follow this pattern √(x^2 + y^2 + z^2) = a natural number (a full number like 24 or 34 but not 2.54) √ = square root , ^2 = to the power of 2, My problem is that whenever I run the function the computer gets stuck and the function never ends so it doesn't return an answer. I would very much appreciate if someone could tell me whats wrong with it (I'm running my programs on the chrome browser console) function mmd() { var chk = false; var a = 1; var b = 1; var c = 1; var d = 1; var e = 0; while(chk != true) { d = Math.sqrt(Math.pow(a, 2)+Math.pow(b, 2)+Math.pow(c, 2)); if( d == d.toFixed(0)) { e++; } else { if((b == 9) && (a == 9) && (c == 9)) {chk = true;} else if((a == 9) && (b == 9)) {c++;} else if(b == 9) {b = 1; a++;} else if(c == 9) {c = 1; b++;} else if(c < 9) {c++;} } } return e }
This part of the code is causing it to never end: if (d == d.toFixed(0)){} else {} If the result of the formula is an integer, you add 1 to e, but you don't increment the other variables, because of the else. It keeps doing e++ for ever. So you need to remove that else. I also took the liberty or removing that chk variable, and instead used while(true), which will be ended by a return of the final result: function mmd() { var a = 1, b = 1, c = 1, d, e = 0; while(true) { d = Math.sqrt(Math.pow(a, 2)+Math.pow(b, 2)+Math.pow(c, 2)); if( d == parseInt(d, 10)) { e++; } if((b == 9) && (a == 9) && (c == 9)) {return e;} else if((a == 9) && (b == 9)) {c++;} else if(b == 9) {b = 1; a++;} else if(c == 9) {c = 1; b++;} else {c++;} } } alert(mmd());
It gets stuck once it hits the e++ block and never increases a, b, or c. function mmd() { var keepGoing = true; var a = 1, b = 1, c = 1, d, e = 0; while(keepGoing) { // calculate d d = Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2) + Math.pow(c, 2)); // check if it is a whole number if(d == d.toFixed(0)) e++; // if we're done then stop if(a == 9 && b == 9 && c == 9){ keepGoing = false; } // if c is less than 9 then increase it else if(c < 9){ c++; } // if c is 9 and b is less than 9 then set c back to 1 and increase b else if(b < 9){ c = 1; b++; } // if c is 9 and b is 9 then set both back to 1 and increase a else if(a < 9){ c = b = 1; a++; } } return e; }
How to Load a javascript file and execute its functions with given parameters in Python 3.4?
For example, a js file called x.js (it's very simple just for explanation): function func2(x, y) { return x + y } function func1(x, y) { return func2(x, y) } Now the module name is jstopy: import jstopy jsobj = jstopy.load("x.js") jsobj.call("func1",1,2) # will return 3 I've searched answer for a long time. Answers such as this are all for python 2 version. Execjs, pyv8 I've all tried. You can see my final goal in this question. I've tried to reimplement it to Python but I failed, it's simply beyond my current js skills. Update the encryption is done by the function do_encrypt: \* ori_password.value is the original password string a user entered en_password.value will be set to the encrypt password*\ function do_encrypt(ori_password, en_password) { var rsa = new RSAKey(); rsa.setPublic(rsa_key,'10001'); var en_pwd = document.getElementById(en_password); var pwd = document.getElementById(ori_password); var pwd_value = pwd.value; var sts = document.getElementById('sts').value; if(pwd_value.length!=0){ var res = rsa.encrypt(pwd_value+"\n"+sts); if(res) { en_pwd.value = hex2b64(res); pwd.value = ""; } } } The content of js file is (if needed): var b64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; var b64pad = "="; function hex2b64(d) { var b; var e; var a = ""; for (b = 0; b + 3 <= d.length; b += 3) { e = parseInt(d.substring(b, b + 3), 16); a += b64map.charAt(e >> 6) + b64map.charAt(e & 63) } if (b + 1 == d.length) { e = parseInt(d.substring(b, b + 1), 16); a += b64map.charAt(e << 2) } else { if (b + 2 == d.length) { e = parseInt(d.substring(b, b + 2), 16); a += b64map.charAt(e >> 2) + b64map.charAt((e & 3) << 4) } } while ((a.length & 3) > 0) { a += b64pad } return a } function b64tohex(e) { var c = ""; var d; var a = 0; var b; for (d = 0; d < e.length; ++d) { if (e.charAt(d) == b64pad) { break } v = b64map.indexOf(e.charAt(d)); if (v < 0) { continue } if (a == 0) { c += int2char(v >> 2); b = v & 3; a = 1 } else { if (a == 1) { c += int2char((b << 2) | (v >> 4)); b = v & 15; a = 2 } else { if (a == 2) { c += int2char(b); c += int2char(v >> 2); b = v & 3; a = 3 } else { c += int2char((b << 2) | (v >> 4)); c += int2char(v & 15); a = 0 } } } } if (a == 1) { c += int2char(b << 2) } return c } function b64toBA(e) { var d = b64tohex(e); var c; var b = new Array(); for (c = 0; 2 * c < d.length; ++c) { b[c] = parseInt(d.substring(2 * c, 2 * c + 2), 16) } return b } function do_encrypt(e, i) { var c = new RSAKey(); var h = "A86C210DEB066606F7BB171ACD3EB98A7978833747B7CF488C788954785FFE58839BE7F9E490F12FFE7A6F3D31D993936D20245ECB6A40713999A8D472B89D0F3113226DA30656CD84B186FA4EC28A8A5AEF8781FC3A49B6C504BD9094523E930E754A12C9A0A54D474A99F0B754B047B0BFAAE7A6D6C97DA2D4C2623A6083B3"; c.setPublic(h, "10001"); var b = document.getElementById(i); var d = document.getElementById(e); var a = d.value; var g = document.getElementById("sts").value; if (a.length != 0) { var f = c.encrypt(a + "\n" + g); if (f) { b.value = hex2b64(f); d.value = "" } } } var dbits; var canary = 244837814094590; var j_lm = ((canary & 16777215) == 15715070); function BigInteger(e, d, f) { if (e != null) { if ("number" == typeof e) { this.fromNumber(e, d, f) } else { if (d == null && "string" != typeof e) { this.fromString(e, 256) } else { this.fromString(e, d) } } } } function nbi() { return new BigInteger(null) } function am1(f, a, b, e, h, g) { while (--g >= 0) { var d = a * this[f++] + b[e] + h; h = Math.floor(d / 67108864); b[e++] = d & 67108863 } return h } function am2(f, q, r, e, o, a) { var k = q & 32767, p = q >> 15; while (--a >= 0) { var d = this[f] & 32767; var g = this[f++] >> 15; var b = p * d + g * k; d = k * d + ((b & 32767) << 15) + r[e] + (o & 1073741823); o = (d >>> 30) + (b >>> 15) + p * g + (o >>> 30); r[e++] = d & 1073741823 } return o } function am3(f, q, r, e, o, a) { var k = q & 16383, p = q >> 14; while (--a >= 0) { var d = this[f] & 16383; var g = this[f++] >> 14; var b = p * d + g * k; d = k * d + ((b & 16383) << 14) + r[e] + o; o = (d >> 28) + (b >> 14) + p * g; r[e++] = d & 268435455 } return o } if (j_lm && (navigator.appName == "Microsoft Internet Explorer")) { BigInteger.prototype.am = am2; dbits = 30 } else { if (j_lm && (navigator.appName != "Netscape")) { BigInteger.prototype.am = am1; dbits = 26 } else { BigInteger.prototype.am = am3; dbits = 28 } } BigInteger.prototype.DB = dbits; BigInteger.prototype.DM = ((1 << dbits) - 1); BigInteger.prototype.DV = (1 << dbits); var BI_FP = 52; BigInteger.prototype.FV = Math.pow(2, BI_FP); BigInteger.prototype.F1 = BI_FP - dbits; BigInteger.prototype.F2 = 2 * dbits - BI_FP; var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz"; var BI_RC = new Array(); var rr, vv; rr = "0".charCodeAt(0); for (vv = 0; vv <= 9; ++vv) { BI_RC[rr++] = vv } rr = "a".charCodeAt(0); for (vv = 10; vv < 36; ++vv) { BI_RC[rr++] = vv } rr = "A".charCodeAt(0); for (vv = 10; vv < 36; ++vv) { BI_RC[rr++] = vv } function int2char(a) { return BI_RM.charAt(a) } function intAt(b, a) { var d = BI_RC[b.charCodeAt(a)]; return (d == null) ? -1 : d } function bnpCopyTo(b) { for (var a = this.t - 1; a >= 0; --a) { b[a] = this[a] } b.t = this.t; b.s = this.s } function bnpFromInt(a) { this.t = 1; this.s = (a < 0) ? -1 : 0; if (a > 0) { this[0] = a } else { if (a < -1) { this[0] = a + DV } else { this.t = 0 } } } function nbv(a) { var b = nbi(); b.fromInt(a); return b } function bnpFromString(h, c) { var e; if (c == 16) { e = 4 } else { if (c == 8) { e = 3 } else { if (c == 256) { e = 8 } else { if (c == 2) { e = 1 } else { if (c == 32) { e = 5 } else { if (c == 4) { e = 2 } else { this.fromRadix(h, c); return } } } } } } this.t = 0; this.s = 0; var g = h.length, d = false, f = 0; while (--g >= 0) { var a = (e == 8) ? h[g] & 255 : intAt(h, g); if (a < 0) { if (h.charAt(g) == "-") { d = true } continue } d = false; if (f == 0) { this[this.t++] = a } else { if (f + e > this.DB) { this[this.t - 1] |= (a & ((1 << (this.DB - f)) - 1)) << f; this[this.t++] = (a >> (this.DB - f)) } else { this[this.t - 1] |= a << f } } f += e; if (f >= this.DB) { f -= this.DB } } if (e == 8 && (h[0] & 128) != 0) { this.s = -1; if (f > 0) { this[this.t - 1] |= ((1 << (this.DB - f)) - 1) << f } } this.clamp(); if (d) { BigInteger.ZERO.subTo(this, this) } } function bnpClamp() { var a = this.s & this.DM; while (this.t > 0 && this[this.t - 1] == a) { --this.t } } function bnToString(c) { if (this.s < 0) { return "-" + this.negate().toString(c) } var e; if (c == 16) { e = 4 } else { if (c == 8) { e = 3 } else { if (c == 2) { e = 1 } else { if (c == 32) { e = 5 } else { if (c == 4) { e = 2 } else { return this.toRadix(c) } } } } } var g = (1 << e) - 1, l, a = false, h = "", f = this.t; var j = this.DB - (f * this.DB) % e; if (f-- > 0) { if (j < this.DB && (l = this[f] >> j) > 0) { a = true; h = int2char(l) } while (f >= 0) { if (j < e) { l = (this[f] & ((1 << j) - 1)) << (e - j); l |= this[--f] >> (j += this.DB - e) } else { l = (this[f] >> (j -= e)) & g; if (j <= 0) { j += this.DB; --f } } if (l > 0) { a = true } if (a) { h += int2char(l) } } } return a ? h : "0" } function bnNegate() { var a = nbi(); BigInteger.ZERO.subTo(this, a); return a } function bnAbs() { return (this.s < 0) ? this.negate() : this } function bnCompareTo(b) { var d = this.s - b.s; if (d != 0) { return d } var c = this.t; d = c - b.t; if (d != 0) { return (this.s < 0) ? -d : d } while (--c >= 0) { if ((d = this[c] - b[c]) != 0) { return d } } return 0 } function nbits(a) { var c = 1, b; if ((b = a >>> 16) != 0) { a = b; c += 16 } if ((b = a >> 8) != 0) { a = b; c += 8 } if ((b = a >> 4) != 0) { a = b; c += 4 } if ((b = a >> 2) != 0) { a = b; c += 2 } if ((b = a >> 1) != 0) { a = b; c += 1 } return c } function bnBitLength() { if (this.t <= 0) { return 0 } return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM)) } function bnpDLShiftTo(c, b) { var a; for (a = this.t - 1; a >= 0; --a) { b[a + c] = this[a] } for (a = c - 1; a >= 0; --a) { b[a] = 0 } b.t = this.t + c; b.s = this.s } function bnpDRShiftTo(c, b) { for (var a = c; a < this.t; ++a) { b[a - c] = this[a] } b.t = Math.max(this.t - c, 0); b.s = this.s } function bnpLShiftTo(j, e) { var b = j % this.DB; var a = this.DB - b; var g = (1 << a) - 1; var f = Math.floor(j / this.DB), h = (this.s << b) & this.DM, d; for (d = this.t - 1; d >= 0; --d) { e[d + f + 1] = (this[d] >> a) | h; h = (this[d] & g) << b } for (d = f - 1; d >= 0; --d) { e[d] = 0 } e[f] = h; e.t = this.t + f + 1; e.s = this.s; e.clamp() } function bnpRShiftTo(g, d) { d.s = this.s; var e = Math.floor(g / this.DB); if (e >= this.t) { d.t = 0; return } var b = g % this.DB; var a = this.DB - b; var f = (1 << b) - 1; d[0] = this[e] >> b; for (var c = e + 1; c < this.t; ++c) { d[c - e - 1] |= (this[c] & f) << a; d[c - e] = this[c] >> b } if (b > 0) { d[this.t - e - 1] |= (this.s & f) << a } d.t = this.t - e; d.clamp() } function bnpSubTo(d, f) { var e = 0, g = 0, b = Math.min(d.t, this.t); while (e < b) { g += this[e] - d[e]; f[e++] = g & this.DM; g >>= this.DB } if (d.t < this.t) { g -= d.s; while (e < this.t) { g += this[e]; f[e++] = g & this.DM; g >>= this.DB } g += this.s } else { g += this.s; while (e < d.t) { g -= d[e]; f[e++] = g & this.DM; g >>= this.DB } g -= d.s } f.s = (g < 0) ? -1 : 0; if (g < -1) { f[e++] = this.DV + g } else { if (g > 0) { f[e++] = g } } f.t = e; f.clamp() } function bnpMultiplyTo(c, e) { var b = this.abs(), f = c.abs(); var d = b.t; e.t = d + f.t; while (--d >= 0) { e[d] = 0 } for (d = 0; d < f.t; ++d) { e[d + b.t] = b.am(0, f[d], e, d, 0, b.t) } e.s = 0; e.clamp(); if (this.s != c.s) { BigInteger.ZERO.subTo(e, e) } } function bnpSquareTo(d) { var a = this.abs(); var b = d.t = 2 * a.t; while (--b >= 0) { d[b] = 0 } for (b = 0; b < a.t - 1; ++b) { var e = a.am(b, a[b], d, 2 * b, 0, 1); if ((d[b + a.t] += a.am(b + 1, 2 * a[b], d, 2 * b + 1, e, a.t - b - 1)) >= a.DV) { d[b + a.t] -= a.DV; d[b + a.t + 1] = 1 } } if (d.t > 0) { d[d.t - 1] += a.am(b, a[b], d, 2 * b, 0, 1) } d.s = 0; d.clamp() } function bnpDivRemTo(n, h, g) { var x = n.abs(); if (x.t <= 0) { return } var k = this.abs(); if (k.t < x.t) { if (h != null) { h.fromInt(0) } if (g != null) { this.copyTo(g) } return } if (g == null) { g = nbi() } var d = nbi(), a = this.s, l = n.s; var w = this.DB - nbits(x[x.t - 1]); if (w > 0) { x.lShiftTo(w, d); k.lShiftTo(w, g) } else { x.copyTo(d); k.copyTo(g) } var p = d.t; var b = d[p - 1]; if (b == 0) { return } var o = b * (1 << this.F1) + ((p > 1) ? d[p - 2] >> this.F2 : 0); var C = this.FV / o, B = (1 << this.F1) / o, A = 1 << this.F2; var u = g.t, s = u - p, f = (h == null) ? nbi() : h; d.dlShiftTo(s, f); if (g.compareTo(f) >= 0) { g[g.t++] = 1; g.subTo(f, g) } BigInteger.ONE.dlShiftTo(p, f); f.subTo(d, d); while (d.t < p) { d[d.t++] = 0 } while (--s >= 0) { var c = (g[--u] == b) ? this.DM : Math.floor(g[u] * C + (g[u - 1] + A) * B); if ((g[u] += d.am(0, c, g, s, 0, p)) < c) { d.dlShiftTo(s, f); g.subTo(f, g); while (g[u] < --c) { g.subTo(f, g) } } } if (h != null) { g.drShiftTo(p, h); if (a != l) { BigInteger.ZERO.subTo(h, h) } } g.t = p; g.clamp(); if (w > 0) { g.rShiftTo(w, g) } if (a < 0) { BigInteger.ZERO.subTo(g, g) } } function bnMod(b) { var c = nbi(); this.abs().divRemTo(b, null, c); if (this.s < 0 && c.compareTo(BigInteger.ZERO) > 0) { b.subTo(c, c) } return c } function Classic(a) { this.m = a } function cConvert(a) { if (a.s < 0 || a.compareTo(this.m) >= 0) { return a.mod(this.m) } else { return a } } function cRevert(a) { return a } function cReduce(a) { a.divRemTo(this.m, null, a) } function cMulTo(a, c, b) { a.multiplyTo(c, b); this.reduce(b) } function cSqrTo(a, b) { a.squareTo(b); this.reduce(b) } Classic.prototype.convert = cConvert; Classic.prototype.revert = cRevert; Classic.prototype.reduce = cReduce; Classic.prototype.mulTo = cMulTo; Classic.prototype.sqrTo = cSqrTo; function bnpInvDigit() { if (this.t < 1) { return 0 } var a = this[0]; if ((a & 1) == 0) { return 0 } var b = a & 3; b = (b * (2 - (a & 15) * b)) & 15; b = (b * (2 - (a & 255) * b)) & 255; b = (b * (2 - (((a & 65535) * b) & 65535))) & 65535; b = (b * (2 - a * b % this.DV)) % this.DV; return (b > 0) ? this.DV - b : -b } function Montgomery(a) { this.m = a; this.mp = a.invDigit(); this.mpl = this.mp & 32767; this.mph = this.mp >> 15; this.um = (1 << (a.DB - 15)) - 1; this.mt2 = 2 * a.t } function montConvert(a) { var b = nbi(); a.abs().dlShiftTo(this.m.t, b); b.divRemTo(this.m, null, b); if (a.s < 0 && b.compareTo(BigInteger.ZERO) > 0) { this.m.subTo(b, b) } return b } function montRevert(a) { var b = nbi(); a.copyTo(b); this.reduce(b); return b } function montReduce(a) { while (a.t <= this.mt2) { a[a.t++] = 0 } for (var c = 0; c < this.m.t; ++c) { var b = a[c] & 32767; var d = (b * this.mpl + (((b * this.mph + (a[c] >> 15) * this.mpl) & this.um) << 15)) & a.DM; b = c + this.m.t; a[b] += this.m.am(0, d, a, c, 0, this.m.t); while (a[b] >= a.DV) { a[b] -= a.DV; a[++b]++ } } a.clamp(); a.drShiftTo(this.m.t, a); if (a.compareTo(this.m) >= 0) { a.subTo(this.m, a) } } function montSqrTo(a, b) { a.squareTo(b); this.reduce(b) } function montMulTo(a, c, b) { a.multiplyTo(c, b); this.reduce(b) } Montgomery.prototype.convert = montConvert; Montgomery.prototype.revert = montRevert; Montgomery.prototype.reduce = montReduce; Montgomery.prototype.mulTo = montMulTo; Montgomery.prototype.sqrTo = montSqrTo; function bnpIsEven() { return ((this.t > 0) ? (this[0] & 1) : this.s) == 0 } function bnpExp(h, j) { if (h > 4294967295 || h < 1) { return BigInteger.ONE } var f = nbi(), a = nbi(), d = j.convert(this), c = nbits(h) - 1; d.copyTo(f); while (--c >= 0) { j.sqrTo(f, a); if ((h & (1 << c)) > 0) { j.mulTo(a, d, f) } else { var b = f; f = a; a = b } } return j.revert(f) } function bnModPowInt(b, a) { var c; if (b < 256 || a.isEven()) { c = new Classic(a) } else { c = new Montgomery(a) } return this.exp(b, c) } BigInteger.prototype.copyTo = bnpCopyTo; BigInteger.prototype.fromInt = bnpFromInt; BigInteger.prototype.fromString = bnpFromString; BigInteger.prototype.clamp = bnpClamp; BigInteger.prototype.dlShiftTo = bnpDLShiftTo; BigInteger.prototype.drShiftTo = bnpDRShiftTo; BigInteger.prototype.lShiftTo = bnpLShiftTo; BigInteger.prototype.rShiftTo = bnpRShiftTo; BigInteger.prototype.subTo = bnpSubTo; BigInteger.prototype.multiplyTo = bnpMultiplyTo; BigInteger.prototype.squareTo = bnpSquareTo; BigInteger.prototype.divRemTo = bnpDivRemTo; BigInteger.prototype.invDigit = bnpInvDigit; BigInteger.prototype.isEven = bnpIsEven; BigInteger.prototype.exp = bnpExp; BigInteger.prototype.toString = bnToString; BigInteger.prototype.negate = bnNegate; BigInteger.prototype.abs = bnAbs; BigInteger.prototype.compareTo = bnCompareTo; BigInteger.prototype.bitLength = bnBitLength; BigInteger.prototype.mod = bnMod; BigInteger.prototype.modPowInt = bnModPowInt; BigInteger.ZERO = nbv(0); BigInteger.ONE = nbv(1); function Arcfour() { this.i = 0; this.j = 0; this.S = new Array() } function ARC4init(d) { var c, a, b; for (c = 0; c < 256; ++c) { this.S[c] = c } a = 0; for (c = 0; c < 256; ++c) { a = (a + this.S[c] + d[c % d.length]) & 255; b = this.S[c]; this.S[c] = this.S[a]; this.S[a] = b } this.i = 0; this.j = 0 } function ARC4next() { var a; this.i = (this.i + 1) & 255; this.j = (this.j + this.S[this.i]) & 255; a = this.S[this.i]; this.S[this.i] = this.S[this.j]; this.S[this.j] = a; return this.S[(a + this.S[this.i]) & 255] } Arcfour.prototype.init = ARC4init; Arcfour.prototype.next = ARC4next; function prng_newstate() { return new Arcfour() } var rng_psize = 256; var rng_state; var rng_pool; var rng_pptr; function rng_seed_int(a) { rng_pool[rng_pptr++] ^= a & 255; rng_pool[rng_pptr++] ^= (a >> 8) & 255; rng_pool[rng_pptr++] ^= (a >> 16) & 255; rng_pool[rng_pptr++] ^= (a >> 24) & 255; if (rng_pptr >= rng_psize) { rng_pptr -= rng_psize } } function rng_seed_time() { rng_seed_int(new Date().getTime()) } if (rng_pool == null) { rng_pool = new Array(); rng_pptr = 0; var t; if (navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) { var z = window.crypto.random(32); for (t = 0; t < z.length; ++t) { rng_pool[rng_pptr++] = z.charCodeAt(t) & 255 } } while (rng_pptr < rng_psize) { t = Math.floor(65536 * Math.random()); rng_pool[rng_pptr++] = t >>> 8; rng_pool[rng_pptr++] = t & 255 } rng_pptr = 0; rng_seed_time() } function rng_get_byte() { if (rng_state == null) { rng_seed_time(); rng_state = prng_newstate(); rng_state.init(rng_pool); for (rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) { rng_pool[rng_pptr] = 0 } rng_pptr = 0 } return rng_state.next() } function rng_get_bytes(b) { var a; for (a = 0; a < b.length; ++a) { b[a] = rng_get_byte() } } function SecureRandom() {} SecureRandom.prototype.nextBytes = rng_get_bytes; function parseBigInt(b, a) { return new BigInteger(b, a) } function linebrk(c, d) { var a = ""; var b = 0; while (b + d < c.length) { a += c.substring(b, b + d) + "\n"; b += d } return a + c.substring(b, c.length) } function byte2Hex(a) { if (a < 16) { return "0" + a.toString(16) } else { return a.toString(16) } } function pkcs1pad2(e, h) { if (h < e.length + 11) { alert("Message too long for RSA"); return null } var g = new Array(); var d = e.length - 1; while (d >= 0 && h > 0) { var f = e.charCodeAt(d--); if (f < 128) { g[--h] = f } else { if ((f > 127) && (f < 2048)) { g[--h] = (f & 63) | 128; g[--h] = (f >> 6) | 192 } else { g[--h] = (f & 63) | 128; g[--h] = ((f >> 6) & 63) | 128; g[--h] = (f >> 12) | 224 } } } g[--h] = 0; var b = new SecureRandom(); var a = new Array(); while (h > 2) { a[0] = 0; while (a[0] == 0) { b.nextBytes(a) } g[--h] = a[0] } g[--h] = 2; g[--h] = 0; return new BigInteger(g) } function RSAKey() { this.n = null; this.e = 0; this.d = null; this.p = null; this.q = null; this.dmp1 = null; this.dmq1 = null; this.coeff = null } function RSASetPublic(b, a) { if (b != null && a != null && b.length > 0 && a.length > 0) { this.n = parseBigInt(b, 16); this.e = parseInt(a, 16) } else { alert("Invalid RSA public key") } } function RSADoPublic(a) { return a.modPowInt(this.e, this.n) } function RSAEncrypt(d) { var a = pkcs1pad2(d, (this.n.bitLength() + 7) >> 3); if (a == null) { return null } var e = this.doPublic(a); if (e == null) { return null } var b = e.toString(16); if ((b.length & 1) == 0) { return b } else { return "0" + b } } RSAKey.prototype.doPublic = RSADoPublic; RSAKey.prototype.setPublic = RSASetPublic; RSAKey.prototype.encrypt = RSAEncrypt;