I want to save my formulas to SQL and use it in both the controller side and javascript side on my .net core project.
{H}+({FA}*2)+{VW}
Formulas are like this format. I want to change values of H, FA and VW with numbers.
string str2 = "{H}+({FA}*2)+{VW}";
string str3 = string.Format(str2, 60, 10, 20);
string value = new DataTable().Compute(str, null).ToString();
I can calculate like this on the controller side. (If there is a better way for it i can get advice too.)
I need to do on JavaScript side too. What should I do?
EDIT;
Btw C# code doesn't work, here is the working one i need a modular thing but i don't know how to do it.
var H = "150";
var VW = "200";
var FA = "20";
string str = $"{H}+{VW}*2";
string value = new DataTable().Compute(str, null).ToString();
I can use string.replace but I've 26 variable and will be complex. I'm adding more examples to formulas.
string formula1 = {H}+({FA}*2)+{VW};
string formula2 = {W}+({FA}*2)+{HW};
string formula3 = {FA}*2+{GFH}-{MTF};
string formula4 = {VSP}/{FA}+{GFV}*(A+B+C);
string formula5 = {TH}+{W}*2+{FT}*2;
***EDIT2:
I'm thinking about to use this on C# side.
public void CalculateTest()
{
List<varKeyDto> varKeys = new List<varKeyDto>(){
new varKeyDto(){
Variable = "H",
Value ="150"
},
new varKeyDto(){
Variable = "VW",
Value ="200"
},
new varKeyDto(){
Variable = "FA",
Value ="20"
},
};
string formula = "{H}+({FA}*2)+{VW}";
string cmptd = ReturnFormula(formula, varKeys);
}
public string ReturnFormula(string formula, List<varKeyDto> varKeys)
{
string formulaString = formula;
foreach (var varKey in varKeys)
{
formulaString = formulaString.Replace("{" + varKey.Variable + "}", varKey.Value);
}
string value = new DataTable().Compute(formulaString, null).ToString();
return value;
}
You could process the string to extract the variable names and make it valid JavaScript code and use all that to create a Function, here is an example:
const str = '{H}+({FA}*2)+{VW}';
const vars = str.match(/{[A-Z]+}/g).map(v => v.replace(/[{}]/g, ''));
const fnBody = str.replace(/[{}]/g, '');
const fn = new Function(...vars, `return ${fnBody}`);
const result = fn(60, 10, 20);
console.log(result);
The generated function looks something like this:
function (H, FA, VW) {
return H+(FA*2)+VW
}
You cannot format string with such custom literals, they have to be like - {0} {1} {2} and so on.
You can use .Replace instead -
var formulaString = formula.Replace("{H}", "1").Replace("{FA}", "2").Replace("{VW}", "3");
string value = new DataTable().Compute(formulaString, null).ToString();
In javascript you can use .replaceAll-
var formula = "{H}+({FA}*2)+{VW}";
var formulaString = formula.replaceAll("{H}", 1).replaceAll("{FA}", 2).replaceAll("{VW}", 3)
console.log(eval(formulaString));
Related
I'm trying to create SHA-1 hash on the client-side. I'm trying to do this with Web Crypto API but when I'm comparing the output to what various online tools give me, the result is completely different. I think the problem is in ArrayBuffer to Hex conversion. Here is my code:
function generateHash() {
var value = "mypassword";
var crypto = window.crypto;
var buffer = new ArrayBuffer(value);
var hash_bytes = crypto.subtle.digest("SHA-1", buffer);
hash_bytes.then(value => document.write([...new Uint8Array(value)].map(x => x.toString(16).padStart(2, '0')).join('')));
}
Output of document.write should be:
91dfd9ddb4198affc5c194cd8ce6d338fde470e2
But it's not, I get a completely different hash of different length (should be 40). Could I have some advise on the problem? Thanks.
The problem seems to be more the input conversion from a string to an ArrayBuffer. E.g. with str2ab() the code works:
generateHash();
function generateHash() {
var value = "mypassword";
var crypto = window.crypto;
var buffer = str2ab(value); // Fix
var hash_bytes = crypto.subtle.digest("SHA-1", buffer);
hash_bytes.then(value => document.write([...new Uint8Array(value)].map(x => x.toString(16).padStart(2, '0')).join('')));
}
// https://stackoverflow.com/a/11058858
function str2ab(str) {
const buf = new ArrayBuffer(str.length);
const bufView = new Uint8Array(buf);
for (let i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
with the expected output:
91dfd9ddb4198affc5c194cd8ce6d338fde470e2
Using the debugger, it looks like var buffer = new ArrayBuffer(value); results in buffer being an empty ArrayBuffer. The text string stored in value must be utf-8 encoded in order to be correctly converted to bytes, which can then by passed as an input to the crypto.subtle.digest() function.
Try changing:
var buffer = new ArrayBuffer(value);
to:
var buffer = new TextEncoder("utf-8").encode(value);
This creates a Uint8Array (as expected by crypto.subtle.digest()) consisting of the bytes resulting from utf-8 encoding the text string in 'value'. This should solve the problem and produce the result that you are expecting.
I am following the solutions from here:
How can I return a JavaScript string from a WebAssembly function
and here:
How to return a string (or similar) from Rust in WebAssembly?
However, when reading from memory I am not getting the desired results.
AssemblyScript file, helloWorldModule.ts:
export function getMessageLocation(): string {
return "Hello World";
}
index.html:
<script>
fetch("helloWorldModule.wasm").then(response =>
response.arrayBuffer()
).then(bytes =>
WebAssembly.instantiate(bytes, {imports: {}})
).then(results => {
var linearMemory = results.instance.exports.memory;
var offset = results.instance.exports.getMessageLocation();
var stringBuffer = new Uint8Array(linearMemory.buffer, offset, 11);
let str = '';
for (let i=0; i<stringBuffer.length; i++) {
str += String.fromCharCode(stringBuffer[i]);
}
debugger;
});
</script>
This returns an offset of 32. And finally yields a string that starts too early and has spaces between each letter of "Hello World":
However, if I change the array to an Int16Array, and add 8 to the offset (which was 32), to make an offset of 40. Like so:
<script>
fetch("helloWorldModule.wasm").then(response =>
response.arrayBuffer()
).then(bytes =>
WebAssembly.instantiate(bytes, {imports: {}})
).then(results => {
var linearMemory = results.instance.exports.memory;
var offset = results.instance.exports.getMessageLocation();
var stringBuffer = new Int16Array(linearMemory.buffer, offset+8, 11);
let str = '';
for (let i=0; i<stringBuffer.length; i++) {
str += String.fromCharCode(stringBuffer[i]);
}
debugger;
});
</script>
Then we get the correct result:
Why does the first set of code not work like its supposed to in the links I provided? Why do I need to change it to work with Int16Array to get rid of the space between "H" and "e" for example? Why do I need to add 8 bytes to the offset?
In summary, what on earth is going on here?
Edit: Another clue, is if I use a TextDecoder on the UInt8 array, decoding as UTF-16 looks more correct than decoding as UTF-8:
AssemblyScript uses utf-16: https://github.com/AssemblyScript/assemblyscript/issues/43
Additionally AssemblyScript stores the length of the string in the first 32 or 64 bits.
That's why my code behaves differently. The examples in the links at the top of this post were for C++ and Rust, which do string encoding differently
I have the following string:
SigV1i8njyrAGrbAfHRNdM3fmEu3kd7keGsqTTDG3Wt3tXqT153eFya2JsEigrK7Pjmh6HhEQLp5bmNXyeHsKNELW7cD3
Is there a javascript string compression function that can shorten this somehow?
I also need a way to extract it back to its original string state.
The idea is to convert the available base62 string into a higher base string. This way you save space. But doing this in vanilla JS (or using Jquery) is difficult because JS doesn't handle big numbers very well. With the help of an external library bigint.js, it is possible. You can test it here. This code was not written by me, but its quite useful:
var base_symbols = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~`!##$%^&*()-_=+[{]}\\|;:'\",<.>/?¿¡";
function baseConvert(src, from_base, to_base, src_symbol_table, dest_symbol_table) {
// From: convert.js: http://rot47.net/_js/convert.js
// Modified by MLM to work with BigInteger: https://github.com/peterolson/BigInteger.js
src_symbol_table = src_symbol_table ? src_symbol_table : base_symbols;
dest_symbol_table = dest_symbol_table ? dest_symbol_table : src_symbol_table;
if(from_base > src_symbol_table.length || to_base > dest_symbol_table.length) {
console.warn("Can't convert", src, "to base", to_base, "greater than symbol table length. src-table:", src_symbol_table.length, "dest-table:", dest_symbol_table.length);
return false;
}
var val = bigInt(0);
for(var i = 0; i < src.length; i ++) {
val = val.multiply(from_base).add(src_symbol_table.indexOf(src.charAt(i)));
}
if(val.lesser(0)) {
return 0;
}
var r = val.mod(to_base);
var res = dest_symbol_table.charAt(r);
var q = val.divide(to_base);
while(!q.equals(0)) {
r = q.mod(to_base);
q = q.divide(to_base);
res = dest_symbol_table.charAt(r) + res;
}
return res;
}
var input = 'SigV1i8njyrAGrbAfHRNdM3fmEu3kd7keGsqTTDG3Wt3tXqT153eFya2JsEigrK7Pjmh6HhEQLp5bmNXyeHsKNELW7cD3';
var a = baseConvert(input, 62, 80);
baseConvert(a, 80, 62);
The resultant output converts 94 characters into 82 characters:
SigV1i8njyrAGrbAfHRNdM3fmEu3kd7keGsqTTDG3Wt3tXqT153eFya2JsEigrK7Pjmh6HhEQLp5bmNXyeHsKNELW7cD3
$sIn3#WAto¿rf<zVn"+:Pkgq;&x.fciVZC7O)`0ii+sf/\X¿CM9Ad!0Z^q?t6uK=w}S8=JZhboIHd'fY\]Qf
SigV1i8njyrAGrbAfHRNdM3fmEu3kd7keGsqTTDG3Wt3tXqT153eFya2JsEigrK7Pjmh6HhEQLp5bmNXyeHsKNELW7cD3
To get better compression, just chanage the base_symbols to include a lot more characters and then convert the input into an even higher base.
Goodday, please i have a code to calculate the efficiency of a generator. The problem is the input fields all add up until the last variable. If all values were 2+2+3+4 which normally sums up into 11 normally, this program doesn't do that instead it just adds the 4 as in 2+2+3+4 equals 74.
That's the formula for calculating the efficiency of a generator.
$('.efmit').on('click', function efficiency() {
var vI = $('.I').val();
var vV = $('.V').val();
var ia = $('.ia').val();
var If = $('.If').val();
var Ra = $('.Ra').val();
var closs = $('.closs').val();
var vi_combo = vI*vV;
var ias = (ia*ia)*Ra;
var iv = If*vV;
var cent = 100;
var result = vi_combo+ias + iv;
var finalR = result + closs;
window.alert(finalR);
})
jQuery val method like $('.closs').val() returns String type variable not Number type.
You can cast type of variable to solve the problem.
var closs = Number($('.closs').val());
The reason is your program treated your variable as a string
try converting them to integer by parsing them like this parseInt(yourVariable).
suppose i have 10 localstorage like blow:
localStorage.setItem("item01","this is a value/100");
localStorage.setItem("item02","this new is a value/110");
localStorage.setItem("item03","this is a good value/120");
localStorage.setItem("item04","this is a nice value/130");
I need a java script code to check if the key of for example item01 is not 0 then put the data of item01 before / to xyz and the data after / to rfv variable.
I would suppose you split the data-string along the character "/". Something like:
var lsData = localStorage.getItem("item01");
var dataArray = lsData.split("/");
if(dataArray.length === 2){
var xyz = dataArray[0];
var rfv = dataArray[1];
}
else{
... error-code (could not split exactly)...
}
This is an answer to your question "get value of string before and after / in javascript".
Like I stated in the comments you can split a string into an array of substrings using a delimiter.
jsfiddle
var str= "this is a value/100";
var temp=str.split("/");
var xyz = temp[0]; //->this is a value
var rfv = temp[1]; //->100
alert('xyz = '+xyz+'\nrfv = '+rfv);
this should do it...
I'm assuming you know how to get the localStorage value, so I'm just posting an example.
var a = "this is a value/100"
var b = /^(.*?)\/(\w+)/.exec(a);
var text = b[1]
var value = b[2]