What is the best way to make a prompt into an integer in JS? [duplicate] - javascript

This question already has answers here:
How to get numeric value from a prompt box? [duplicate]
(6 answers)
Closed 9 months ago.
I am writing a program to perform "Russian Math" (using the numberphile youtube video on it as my basis for the algorithm). It works. But, to "prove" that it works, I'm giving the user the ability to try using their own numbers as input.
When I assign numbers to the variables myself, it works without fail. However, when I use prompt var numberOne = prompt('What is the first number you want to multiply?'); on one variable (with the other being assigned myself)it works. But as soon as I prompt the user for both numbers it won't work. Presumably because a string can be converted to an integer when an operation is performed on it (multiplied by an integer), but it does not seem to work when both are strings.
Adding another line to reset the prompt variable to an integer using parse seems like too much extra.
var numberOne = prompt('What is the first number you want to multiply?');
var numberTwo = prompt('What is the second number you want to multiply?');
var numberOneInt = parseInt(numberOne);
var numberTwoInt = parseInt(numberTwo);
Is this really the best way to do it?

For a prompt, yes, that is pretty much what you want to do. Prompt returns a string, so you need to convert it. There are other ways, i.e. Number(numberOne), but parseInt is fine. They have slightly different behaviors, but for your case they're mostly the same. (parseInt stops parsing at the first non-number, while Number type-casting attempts to convert the whole thing).
And kudos for figuring out the edge behavior of having one string and one int multiplied together.
In general, most developers prefer using inputs on the page rather than prompts. The problem with prompts is that they interrupt the user's control of the page. As a bonus, with inputs you can set type=number to give the users number controls on some devices and limit the input to actual numbers.
Edit
I don't ever use prompt, so I was reading up on them. One thing to look out for is if the user hits escape, it returns null, which may break your code. You could prevent that by just checking for it first, i.e. if(numberOne){ ... }

Related

Regex for finding all the numbers between any two numeric values (range) in JavaScript [duplicate]

This question already has answers here:
How to match numbers between X and Y with regexp?
(7 answers)
Closed 7 years ago.
First of all, i know Regular expressions isn't the best tool to achieve what I want here. I have done enough research to know that bit. Still, The problem I am stuck in requires me to make up a regex to find the values between some lower and upper bound values.
So here is the problem, I have a large set of data, let's say ranging between 1 and 1000000. That data is not under my direct control, I cannot manipulate the data directly. Only way of finding out (searching) some values from that data is regex.. Now, the user can give two values, a minimum value and a maximum value and I need to construct a regex based on these two values and then query the large data set using the regex to get all the values lying between the set range. So, if my data contains [1,5,7,9,15,30,45,87] and user sets the range min:10, max:40. The regex should filter out values 15, 30.
From whatever I have searched, I know it is very much possible to build a regex for finding out values between fixed values (if we know them beforehand) for example, values between 1 to 100 can be found by:
^(100|[1-9][0-9]?)$
But what gets so tricky about my problem is that the input range can be anything from pretty much 1 digit values to up to 10 digit values. 10000-550000 can be an example user input for a large data set.
I know this will require some complex logic and loops involved on the basis of number of digits in the lower bound and number of digits in the upper bound of the range and then some recursive or other magical logic to build a regex that covers all the number lying in that range.
I've been filling up pages to come up with a logic but I'm afraid it surpasses my knowledge of regex. If anyone has ever done something like this before or try to point me in the right direction or attempt it him/herself - it'll be quite helpful. Thanks.
The language I will be using this in is JavaScript and I read somewhere that JS doesn't support conditional regex, keeping that in mind, solution doesn't have to be in specific to a language.
If your task is to get numbers between min and max value from the dataset, you can try filter method.
Var filteredResults = Dataset.filter(function(item){
If(item < max && item > min)
Return item
}
)

How to make this login/redirect method more secure

I have an application which sends e-mails to users, each e-mail containing a link to a page the user must access.
The link is an md5 of an unique id + a random number.
The link looks like: www.domain.com/index.php?id_page=<the md5>
On the index page i save the $_GET["id_page"] within a session variable, $_SESSION["id_page"] and I redirect the user to the page which he must see (the user is redirected to that page only if the link contains id_page).
How can I improve this method and make it more secure? How can I guarantee that the users enter the page designated to them - and cannot enter any other page?
What you are concerned with here is a matter of time, rather than a matter of security :). If you allow anyone to guess an infinite number of id_page values, then given enough time, eventually someone will happen upon a random valid id_page value.
Your only real defense against this is to increase the length of your hash, causing it to take (on average) more time to happen upon a random valid id_page (on the order of months or years). This could be accomplished by using sha256 or sha512 rather than md5.
Another approach is to lock someone out for a period of time if they have, for example, 3 consecutive incorrect guesses at an id_page value. This will greatly decrease the number of values they can attempt in a given period of time.
Lastly, If the user is already logged in at the time of redirect then you could also store the hashes you generate in a database table. That way you can map a particular hash to one and only one userid in the table. If a user attempts to visit a hash page to which they don't correspond in the DB, then you could redirect them elsewhere.
You can add their email in the URL. the probability of someone guessing someone else's email and the associated hash is just about 0.
One method that can work quite well for preventing guessing ID numbers is to add some sort of padding to the ID and then convert it to base32. Of course, this doesn't eliminate the ability to guess an ID entirely, but it does make it a little more time consuming for anyone who is snooping around.
If you have the URL www.domain.com/index.php?id_page=1, you could convert the id to something unique in your application, for example:
padded id = id x 9 - 2
7 = 1 x 9 - 2
16 = 2 x 9 -2
25 = 3 x 9 - 2
Then, you can convert the new padded ID to base 32, which would be
7 = G4
16 = GE3A
25 = GI2Q
The new url would then be (for an id of 1):
www.domain.com/index.php?id_page=G4
Using this method, if someone guesses the base 32 of 1-6, it would return a 404, because your ID of 1 is actually being padded out to become 7. Guessing 8-15 wouldn't return a parsed ID because the next id of 2 is padded to 16, and so on.
Not only does this keep the query string smaller in size, but it also doesn't use an obvious MD5 hash which can very easily be sequentially browsed using dictionaries.
If you want the page to be linked to a specific users, well there's no reason why you cannot append more values to the new padded_id (let's call it a hash).
For instance, if you have a user with an ID of 12, and you only want that user to be able to visit a page with an id of 10, you would need to create a hash that comprises of both these values:
page_id(10)-user_id(12), using the above example, this would produce:
(10 x 9 - 2) (12 x 9 - 2)
88-106
HA4A-GEYDM
You now have a nice small hashed link that can be secured to a single user ID. The padding method in the example above is rather simple, but it gives you the overall idea of how to approach the issue.
Don't bother hashing or creating unique ids or anything. Complexity is not going to help you.
Instead, simply generate a random token, and use that. A 256 bit random token should be sufficient for anything you need to do.
So, using mcrypt (a core extension):
$token = strtr(
base64_encode(mcrypt_create_iv(256/8, MCRYPT_DEV_URANDOM)),
'+/',
'-_'
);
That will give you a 44 character result of the alphabet a-zA-Z0-9-_ which contains 256 bits of random entropy.
There's no need to hash the result or anything. The random data is enough.
To understand why, you need to understand The Birthday Problem.
Basically with a 256 bit random value, to have a 1% chance that 2 tokens collide you would need to generate 4.8e37 tokens (that's 48 followed by 36 0's).
To get a 10e-18 chance of collision (which is typically seen as secure) you'd need to generate 4.8e29 tokens.
Since those numbers are WAY more than you'd ever generate, the chance of 2 tokens colliding is infinitesimally small.
The other problem is people guessing the token. Well, MCRYPT_DEV_URANDOM uses the underlying operating system's random pool. Which means that people are way more likely to guess your "unique id and random number" than they are to guess the token generated here.
So, in short, just use a random token and be done :-)

How to "unformat" a numerical string? JavaScript

So I know how to format a string or integer like 2000 to 2K, but how do I reverse it?
I want to do something like:
var string = "$2K".replace("/* K with 000 and remove $ symbol in front of 2 */");
How do I start? I am not very good regular expressions, but I have been taking some more time out to learn them. If you can help, I certainly appreciate it. Is it possible to do the same thing for M for millions (adding 000000 at the end) or B for billions (adding 000000000 at the end)?
var string = "$2K".replace(/\$(\d+)K/, "$1000");
will give output as
2000
I'm going to take a different approach to this, as the best way to do this is to change your app to not lose the original numeric information. I recognize that this isn't always possible (for example, if you're scraping formatted values...), but it could be useful way to think about it for other users with similar question.
Instead of just storing the numeric values or the display values (and then trying to convert back to the numeric values later on), try to update your app to store both in the same object:
var value = {numeric: 2000, display: '2K'}
console.log(value.numeric); // 2000
console.log(value.display); // 2K
The example here is a bit simplified, but if you pass around your values like this, you don't need to convert back in the first place. It also allows you to have your formatted values change based on locale, currency, or rounding, and you don't lose the precision of your original values.

Search string for numbers

I have a javascript chat bot where a person can type into an input box any question they like and hope to get an accurate answer. I can do this but I know I'm going about this all wrong because I don't know what position the number will appear in the sentence. If a person types in exactly:
what's the square root of 5 this works fine.
If he types in things like this it doesn't.
what is the square root of the 5
the square root of 5 is what
do you know what the square root of 5 is
etc
I need to be able to determine where the number appears in the sentence then do the calculation from there. Note the line below is part of a bigger working chatbot. In the line below I'm just trying to be able to answer any square root question regardless of where the number appears in the sentence. I also know there are many pitfalls with an open ended input box where a person can type anything such as spelling errors etc. This is just for entertainment not a serious scientific project. :)
if(
(word[0]=="what's") &&
(word[1]=="the") &&
(word[2]=="square") &&
(word[3]=="root") &&
(word [4]=="of") &&
(input.search(/\d{1,10}/)!=-1) &&
(num_of_words==6)
){
var root= word[5];
if(root<0){
document.result.result.value = "The square root of a negative number is not possible.";
}else{
word[5] = Math.sqrt(root);
word[5] = Math.round(word[5]*100)/100
document.result.result.value = "The square root of "+ root +" is "+ word[5] +".";
}
return true;
}
Just to be clear the bot is written using "If statemments" for a reason. If the input in this case doesn't include the words "what" and "square root" and "some number" the line doesn't trigger and is answered further down by the bot with a generic "I don't know type of response". So I'm hoping any answer will fit the format I am using. Be kind, I'm new here. I like making bots but I'm not much of a programmer. Thanks.
You can do this using a regular expression.
"What is the sqrt of 5?".match(/\d+/g);
["5"]
The output is an array containing all of the numbers found in the string. If you have more than one, like "Is the square root of 100 10?" then it will be
"Is the square root of 100 10?".match(/\d+/g);
["100", "10"]
so you can pick what number you want to use in your script.
You will need to use regular expressions, if you do not know what they are you should look them up as it would take too long to explain them in this response. Here is a useful website for regular expressions in JavaScript https://developer.mozilla.org/en/JavaScript/Guide/Regular_Expressions.
Assuming that you know regular expressions you should first search for numbers and store all the numbers that you find, if no numbers are found print out an error message. As an added note, you may what to consider searching for mathematical constants such as pi or e. This should work
nums = someString./\d+|pi|e/gi
The next part is going to be hard but to boil it down to is core concept, you need to look for key words such as 'square root', 'times', or 'plus'. You should do this word by word going left to right. For example if a user inputs
What is 5 plus 3 minus 8?
you should detect the plus before the minus, while if this is inputted
What is 5 minus 3 plus 8?
You should detect the minus before the plus.
For operations that uses two numbers you need to take the first two numbers that you found and do the operation and replace the two numbers with the result. I am trying to use reverse polish notation if you do not quite understand what I am trying to do, look it up if do not know what it is.
I hope I understood your question correctly and provided some help to coming to a solution because what you asked is very hard but seems like fun. Good luck. Also as a warning I am not considering order of operations in my response.

How to compare locale dependent float numbers?

I need to compare a float value entered in a web form against a range. The problem is that the client computers may have various locale settings, meaning that user may use either "." or "," to separate the integer part from decimal one.
Is there a simple way to do it? As it is for an intranet and that they are only allowed to use IE, a VBScript is fine, even if I would prefer to use JavaScript.
EDIT: Let me clarify it a bit:
I cannot rely on the system locale, because, for example, a lot of our french customers use a computer with an english locale, even if they still use the comma to fill data in the web forms.
So I need a way to perform a check accross multiple locale "string to double" conversion.
I know that the raise condition is "what about numbers with 3 decimal digits", but in our environment, this kind of answer never happen, and if it happens, it will be threated as an out of range error due to the multiplication by a thousand, so it's not a real issue for us.
In Javascript use parseFloat on the text value to get a number. Similarly in VBScript use CDbl on the text value. Both should conform to the current locale settings enforce for the user.
This code should work:
function toFloat(localFloatStr)
var x = localFloatStr.split(/,|\./),
x2 = x[x.length-1],
x3 = x.join('').replace(new RegExp(x2+'$'),'.'+x2);
return parseFloat(x3);
// x2 is for clarity, could be omitted:
//=>x.join('').replace(new RegExp(x[x.length-1]+'$'),'.'+x[x.length-1])
}
alert(toFloat('1,223,455.223')); //=> 1223455.223
alert(toFloat('1.223.455,223')); //=> 1223455.223
// your numbers ;~)
alert(toFloat('3.123,56')); //=> 3123.56
alert(toFloat('3,123.56')); //=> 3123.56
What we do is try parsing using the culture of the user and if that doesn't work, parse it using an invariant culture.
I wouldn't know how to do it in javascript or vbscript exactly though.
I used KooiInc's answer but change it a bit, because it didn't reckon with some cases.
function toFloat(strNum) {
var full = strNum.split(/[.,]/);
if (full.length == 1) return parseFloat(strNum);
var back = full[full.length - 1];
var result = full.join('').replace(new RegExp(back + '$'), '.' + back);
return parseFloat(result);
}
Forbid using any thousands separator.
Give the user an example: "Reals should look like this: 3123.56 or 3123,56". Then simply change , to . and parse it.
You can always tell user that he did something wrong with a message like this:
"I don't understand what you mean by "**,**,**".
Please format numbers like "3123.56."

Categories

Resources