Using replace() on decoded URI hex codes with native division operator - javascript

Building a calculator.
var process = "6÷6"; // need to replace division sign with one that javascript can evaluate with
process = encodeURI(process);
process.replace(/%C3%B7/gi,'/'); // replacement step that doesn't work - %C3%B7 is what shows up as the hex divison sign in chrome debugger, not sure why
process = decodeURI(process);
result = eval(process);

You can create an object with properties set to arithmetic operators. Note, .replace() may not be necessary
var map = {"÷":"/"};
var operatorType = "÷";
var process = "6" + map[operatorType] + "6"; // need to replace division sign with one that javascript can evaluate with
process = encodeURI(process);
process.replace(/%C3%B7/gi,'/'); // replacement step that doesn't work - %C3%B7 is what shows up as the hex divison sign in chrome debugger, not sure why
process = decodeURI(process);
result = eval(process);
document.body.innerHTML = result;

The third line of your code is wrong. You have to assign the return value of the replace function to a variable. The easiest way is to assign it to itself:
process = process.replace(/%C3%B7/gi,'/');
So the whole script code would look like this:
var process = "6÷6"; // need to replace division sign with one that javascript can evaluate with
process = encodeURI(process);
process = process.replace(/%C3%B7/gi,'/'); // replacement step now works
process = decodeURI(process);
result = eval(process);

Related

How to parseInt or ParseInt embedded data with TypeScript in Qualtrics?

Even when I save an integer to embedded data earlier in the survey flow (in previous blocks on different screens), I am not able in Javascript to get the embedded data value, ensure it is parsed as a number/integer, then use it in a loop. Is this something about TypeScript? I didn't see anything about parseInt or ParseInt in the TypeScript documentation.
For example, suppose I do the following:
// Draw a random number
var x = Math.floor(Math.random() * 5);
// Save it in embedded data
Qualtrics.SurveyEngine.setEmbeddedData("foo", x);
// In a later block on a different screen, get the embedded data as an integer
var x_new = "${e://Field/foo}"; // not an int
var x_new = parseInt("${e://Field/foo}"); // doesn't work
var x_new = ParseInt("${e://Field/foo}"); // doesn't work
// Loop using x_new:
for(i = 0; i < x_new; i++) {
console.log(i)
}
Any idea why this isn't working? Perhaps I just don't know how to parseint().
In "normal" JS runtime system, we have parseInt function, the function gets a string (like number string) as a parameter. In this env, we don't support your syntax - "${e://Field/foo}", because it is not a "number string".
In Qualtrics system environment they have parseInt too, but they support their custom syntax "${e://Field/foo}" to get EmbeddedData.
Make sure that your code is running on Qualtrics system environment.
ParseInt is just turning your string into an integer.
Look at the demo below.
let myVar = "${e://Field/foo}"; // This is a string
console.log(myVar); // This prints a string
console.log(parseInt(myVar)); // This prints "NaN", i.e. Not a Number, because the string isn't a representation of a number.

Multiply a number which has a comma with javascript

Im trying to multiply a value which contains a comma(lets keep this comma). I cant find anything that seem to work, as everything that I have tried returns as NaN.
var value = 2,55;
// value = 44.000,55 also possible
var amount = 117;
var total = value * amount;
alert(total);//returns NaN
var value = 2,55;
That is not 2.55; it is 2, a comma and then 55. If I put that into the console of the dev tools of a chromium based browser I get "Uncaught SyntaxError: Unexpected number".
Because it is not valid syntax, in a var expression commas are used to define multiple locals.
JavaScript number literals can only use a period as a decimal separator: while parsing functions (converting from strings at runtime) can supper internationalisation the source code does not.
If you are creating code dynamically, the code to create the code has to handle creating syntactically correct code:
var value = 2.55; // or 4000.55
Assuming you are trying to operate on monetary values, it would be better to get the value as a string and convert it to float then back to string if you want to keep the comma:
var value = "2,55";
var amount = 50123123123;
var total = parseFloat(a.replace(',', '')) + b;
total = total.toString().split("").reverse().join("").split('').reduce((a, e, i)=> a + e + (i % 3 === 2 ? ',' : ''), '');
total=total.split("").reverse().join("");

Is binary hashing possible with CryptoJS?

I want to create an HOTP client using javascript similar to SpeakEasy
The above library is intended for server side javascript usage and it uses NodeJS.
I want to do the same thing on front end javascript in a browser but I haven't been able to use CryptoJS to achieve this behavior.
var key = "abc";
var counter = "123";
// create an octet array from the counter
var octet_array = new Array(8);
var counter_temp = counter;
for (var i = 0; i < 8; i++) {
var i_from_right = 7 - i;
// mask 255 over number to get last 8
octet_array[i_from_right] = counter_temp & 255;
// shift 8 and get ready to loop over the next batch of 8
counter_temp = counter_temp >> 8;
}
// There is no such class called as Buffer on Browsers (its node js)
var counter_buffer = new Buffer(octet_array);
var hash = CryptoJS.HmacSHA1(key,counter_buffer);
document.write("hex value "+ hash);
document.write("hash value "+ CryptoJS.enc.Hex.stringify(hash));
I know this is possible on a native platform like java (android) or objective c (ios)
Here is the corresponding implementation HOTP in Objective C but I doubt if it's possible to do on a web based front end.
Also, I highly doubt if such a thing is secure in browser because javascript is viewable from any browser. Any inputs suggestions would be useful. I am doing this for a POC. I am curious if anyone has used Hotp on web based platform.
There is no such language that supports binary data strings in the code. You need to encode the binary data into some format such as Hex or Base64 and let CryptoJS decode it into it's own internal binary format which you then can pass to the various CryptoJS functions:
var wordArrayFromUtf = CryptoJS.enc.Utf8.parse("test");
var wordArrayFromHex = CryptoJS.enc.Hex.parse("74657374"); // "test"
var wordArrayFromB64 = CryptoJS.enc.Base64.parse("dGVzdA=="); // "test"
Other functions are:
wordArrayFromHex.toString(CryptoJS.enc.Utf8) // "test"
CryptoJS.enc.Utf8.stringify(wordArrayFromB64) // "test"
If you pass a string into a CrypoJS function (not these here), it will be assumed to be a Utf8-encoded string. If you don't want that, you need to decode it yourself.
The code at http://caligatio.github.io/jsSHA/ works fine for SHA-512.
Drop the .js files, look in their test/test.html at line 515. It might look like a string to you but it is binary hex.
So their input is binary which is unmistaken. Don't get hung up on the fact it is sitting in a big string.

converting string to integer in Javascript

I am reading some values from an xml file using JavaScript. Since it is a string, i need to convert it to integer and perform some calculations.
For reading the data from XML file I use this code:
var pop = JSON.stringify(feature.attributes.Total_Pop.value);
which works fine. later I use the following code to convert it to integer:
var popint = parseInt(pop);
This also works fine. But later when I use it to do some math, it returns NAN.
the code I use for Math operation is:
var pop6 = Math.ceil(popint / 30);
What am I doing wrong? any suggestions?
Don't stringify -- just use var pop = feature.attributes.Total_Pop.value;. Calling JSON.stringify wraps the string in extra quotation marks.
var pop = "123"; // "123"
var popint = parseInt(pop); // 123
Vs:
var pop = JSON.stringify("123"); // ""123""
var popint = parseInt(pop); // NaN

Using javascript regex to translate a html

I would like to build my own translation function in javascript.
I already have a function language.lookup(key) which translates a word or expression:
var frenchHello = language.lookup('hello') //'bonjour'
Now I would like to write a function which takes a html string and translates it with my lookup function. In the html string I will have a special syntax for example #[translationkey] that will point out that this word should be translated.
This is the result I want:
var html = '<div><span>#[hello]</span><span>#[sir]</span>'
language.translate(html) //'<div><span>bonjour</span><span>monsieur</span>
How would I write language.translate?
My idea is to filter out my special syntax with regex and then run language.lookup on each key. Maybe with string replace or something.
I suck when it comes to regex and I've only come up with a very incomplete example but I include it anyway so maybe someone get the idea of what I am trying to do. Then if there is a better but complete different solution that is more than welcome.
var value = "#[hello], nice to see you.";
lookup = function(word){
return "bonjour";
};
var res = new RegExp( "\\b(hello)\\b", "gi" ).exec(value)
for (var c1 = 0; c1 < res.length; c1++){
value = value.replace(res[c1], lookup(res[c1]))
}
alert(value) //#[bonjour], nice to see you.
The regex should of course not filter out the word hello but the syntax and then collect the key by grouping or similar.
Can anyone help?
Just use String.replace method's ability to call function specified as second argument to generate replacement text and make a global replace using regexp matching your syntax:
var value = "#[hello], #[sir], nice to see you.";
lookup = function(full_match, word){
if(word == 'hello')
return "bonjour";
if(word == 'sir')
return "monsieur"
};
console.log(value.replace(/#\[(.+?)\]/gi, lookup))
Result:
bonjour, monsieur, nice to see you.
Of course when your replacement list gets bigger, you'd better use lookup object instead of series of ifs in lookup function, but you can really do whatever you want there.
You can try this to find all occurrences:
var re = new RegExp('#\\[([^\\]]+?)\\]', 'gi'),
str = '#[value1] plain text #[value2]',
match;
while (match = re.exec(str)) {
console.log(match);
}
You could use something like:
#\\[[^\\]]*\\]
Which matches the hash followed by an opening square bracket followed by zero or more characters NOT including the closing square bracket, followed by a closed square bracket.
Alternatively, perhaps it would be better to handle the translation at the server side (maybe even through your template engine) and send back to your client the translated response. Otherwise, (depending on the specific problem you are dealing with of course), you might end up sending a lot of data to the browser which might make your application respond slowly.
EDIT:
Here is a working piece of code:
var q="This #[ANIMAL1] was eaten by that #[ANIMAL2]";
var u = {"#[ANIMAL1]":"Lion","#[ANIMAL2]":"Frog"};
function insertAnimal(aString, lookup){
var res = (new RegExp("#\\[[^\\]]*\\]", "gi"))
while (m = res.exec(aString)){
aString = aString.replace(m, lookup[m])
}
return aString;
}
function main(){
alert(insertAnimal(q,u));
}
You can call the "main()" from an HTML document's body onload event
I can compare your requirement to 'resolving template texts within content'. If it is feasible to use Jquery , you should try Handlebars.js
.

Categories