Js Password Array - javascript

My Homework
"Create a basic web page that will update Assignment 3.4. Create an array that will store at least eight valid passwords. Then, ask the user for a password using a prompt dialog. Utilize a for-loop to navigate the password array. If the user's input matches any string in the array, give them feedback that the password is valid. Otherwise, let them know that it is invalid.
You do not necessarily have to include any feature that give them a chance to re-enter the password. This can simply be a one-time search of the password array."
This is for my javascript class... so far I have this:
var accepted_passwords = new Array ( );
accepted_passwords[0] = "Saginaw";
accepted_passwords[1] = "Bay City";
accepted_passwords[2] = "Midland";
accepted_passwords[3] = "Reese";
accepted_passwords[4] = "Millington";
accepted_passwords[5] = "Frankenmuth";
accepted_passwords[6] = "Sheilds";
accepted_passwords[7] = "Birch Run";
var random_bg = new Array ( );
random_bg[0] = "#0000CC";
random_bg[1] = "#33FF33";
random_bg[2] = "#990000";
random_bg[3] = "#9900FF";
random_bg[4] = "#CC0000";
random_bg[5] = "#FF00CC";
var enterpassword;
enterpassword = prompt("Enter Password", "");
for(0 <= i <= 7; enterpassword = accepted_passwords[i];) {
document.body.style.background=random_bg[Math.floor(Math.random()*random_bg.length)];
}
Its supposed to ask for a password... and then if you get it right... it displays one of the five random colors. The random color part works... its the password part that doesn't. I can do this no problem with an if else statement... but apparently my teacher wants a for loop?????? Please help!

I think the answer here is that you've fulfilled the teacher's requirement to use a for loop. However there is nothing stopping you also use one or more if..else constructs too. In fact, if you think about it a bit more, you'll realise there is no way to "check if its a valid password" without an if..else.
A few observations on how to complete your homework:
Your for(...) loop is wrong. for loops always follow the pattern:
for([loop-variable-initialisation];[loop-termination-condition];[loop-variable-increment]
eg, for(var i=0;i<10;i++) // loops for values from 0 to 9
Instead of hard-coding the length of the array, for use in the loop termination condition, it is better to read the .length of the array
You are currently not checking the value entered exists in the array at all. Worse, your actually (trying to) assign each value in the array to the variable holding the user's input: enterpassword = accepted_passwords[i]. This is wrong.

Don't take the statement so literally. He probably means: Use a loop and other required features.
On a side note I would rather use a if(x in y) construct, like described here
EDIT: Removed actual solution.

Related

What is the least issue prone way to separate the first set of numbers from a string?

For context, I have a system that asks a user to give a rating between 1-10. Afterwards, I give them the option to leave any additional notes they would like to leave.
Unfortunately what seems to happen half of the time is that a customer will leave notes along with the initial 1-10 rating. With the interface I am using I have no way of restricting the input to numbers only.
The best solution I would be going for is to simply separate the number from the statement into two separate variables or into an array[0-1].
So basically I have
var responseA = (customer input here)
Then I would need to remove any additional comments they put into the first response
responseA = responseA.someMagic() //This is where I need help
And continue to deal with the remaining interactions and store them as such
var responseB = responseA[1] + ". " + (customer input 2 here)
This will take the second portion of the first response that includes notes and combines those notes with the second response which contains the second portion of notes. If it's possible to have some sort of way to detect that there were notes in the first place that would also be good to avoid
". Thank you."
as opposed to
"Thank you."
Because of the concatenation of the first string in situations it is not necessary.
edit: After rereading this it still seems confusing if you don't know exactly what is going on. Let me show you a real world example:
Q1: Please give a rating between 1-10:
"10! You were very helpful, thank you!"
Q2: If you have any notes you may leave them here:
"Very helpful."
This means that when the system that deals with the ratings from question 1 receives additional strings, it won't count it as a number. I want to remove everything after the 10 and add it to Q2's response to not lose any of their response, but also not store it in the wrong place.
Here is a possibility, using regex to check and split apart the first value:
const combineResponses = (q1, q2) => {
const matches = q1.match(/^(\d*)\W*(.*)/)
return matches[2] ? {
rating: matches[1],
comment: [matches[2], q2].join('. ')
} : {
rating: matches[1],
comment: q2
}
}
console.log(combineResponses(
"10! You were very helpful, thank you!",
"Very helpful."
))
console.log(combineResponses(
"10",
"Very helpful."
))
console.log(combineResponses(
"oops",
"Very helpful."
))
It does nothing to check that the rating is in the right range. Nor does it handle, say 7.4, although it would be easy enough to modify for the latter.
But if you can find a way to separate your initial input in a cleaner way, it would definitely be better to avoid this.
If you are sure the string will always begin with a number for the rating, you could call parseInt() on the string to find out what the number is. If there is a number, you could then use indexOf() to find the first time it appears and cut the string there, otherwise just assume the whole thing was a string.
const userInputs = ['1 thank you', '10thanks', ' 5. random text', 'no rating'];
let length = 1;
let index;
let rating;
let response;
for (const i of userInputs) {
rating = parseInt(i);
if (rating) {
if (rating > 9) {
length = 2;
}
index = i.indexOf(rating);
response = i.substring(index + length).trim();
} else {
response = i;
}
console.log(`${i}, rating: ${rating}, response: ${response}`);
}

Get how many instances of a 'field' are in a text, and append each value with the same 'field' to the same variable

So lets say I have a mailto email in which a checkbox question exists that asks the user to pick the best fruits out of a list of fruits (check all that apply.) They end up with apples, bananas, and pears. The mailto email that they trigger then contains the following (assuming the checkboxes in the question are named bestFruits):
...
bestFruits=apples
bestFruits=bananas
bestFruits=pears
...
So in my javascript file, I have the following line to parse values from the email:
var bestFruits = mail.bodyText.match(/bestFruits=\s*(\S.*\S)\s*/);
So my issue is that this would (presumably) take only one value by the end. What I need, is for the javascript to loop and add each value of bestFruits in the email to the bestFruits var so that each value (apples, bananas, and pears) are all in the bestFruits var.
Is there any way to do this? I tried making a for loop, but I couldn't determine the syntax to loop through the mailto email body and add each instance of bestFruits to the variable.
I'm still extremely new to all this, as I was thrust in recently. If I'm missing something fundamental, I'd appreciate a quick pointing-out. If you require any more info, I'd be happy to try to provide it.
Thanks for reading guys!
You don't need looping. You do need to match all the fruits (as per your example, matching all single words after bestFruits), remove bestFruits= from the matches, join the resulting array and store it in a variable. Like this:
var bestFruits = mail.bodyText.match(/bestFruits=\w+/g)
.map(function(x){return x.split('=')[1]})
.join(',');
What does it do:
Matches all your best fruits.
Takes each bestFruits=abc element and replaces it with abc (i.e., splits with = separator and takes the second part)
Makes the string of your fruits (converts the resulting array to string with , joiner).
You were very close - modified your regex a little bit:
var body = `this=is
an=example
bestFruits=apples
bestFruits=bananas
bestFruits=pears
of=doing
things=ok?
`;
var re = /bestFruits=(.*)/g;
var fruitMatches = body.match(re);
var bestFruits = fruitMatches.map(function(fruitMatch) {
return fruitMatch.split('=')[1];
});
console.log(bestFruits); // ["apples", "bananas", "pears"]
Fiddle

Slicing a string from a textbox

I am trying to take a string entered by user from a textbox. Check the length of that string and if the string is over a given number perform the slice operation on it.
Here's what I came up with but my code does nothing. Checked console, no errors given.
html:
<form id="slice">
Enter a pharse:<input type="text" id="text_box_2"><br>
<input type="button" value="slice" onclick="Slice()">
Result: <input type="text" id="slice_result"><br>
</form>
Javascript function:
function Slice(){
var UserString = document.getElementById("text_box_2").value;
var UserStringValue = UserString.length;
var Result = Userstring.slice(1,6);
if (UserStringValue > 6){
document.getElementById("Slice_result").value = Result;
}
else{
alert("Please enter a longer phrase.")
}
}
what or where did I go wrong?
Be mindful of case-sensitivity.
This:
var Result = Userstring.slice(1,6);
Should be using UserString (capital "S") as defined earlier in your code.
Next, the input ID should be all lowercase, slice_result, to match to HTML, but your code uses different casing:
document.getElementById("Slice_result")
Here's a working JSBin with these fixes.
EDIT: As JaromandaX mentioned in the comments, if you want to take the first 6 characters you should use slice(0, 6).
from cursory reading of your code. it seems caused by this line
var Result = Userstring.slice(1,6);
and also this one
document.getElementById("Slice_result").value = Result
it should be
var Result = UserString.slice(1,6);
and
document.getElementById("slice_result").value = Result
Usually use of the following
var Value = $('#input_id').val();
will pull the requested information for you.
You can also set up arguments for your slice function and pass in the value when you run onclick();
I'd also note that slice() is a current js function, though your implentation with the capital 'S' is some what different, it may be better practice to change that name a bit.

Javascript - Prompt for values (and add values to array) until user inputs a specific value

Ladies and gentlemen,
I'm stuck. I've been pondering this (and obviously have failed since I'm asking for your valuable assistance) in trying to get my code to work.
I need to come up with a simple (...I'm sorry, i'm new to this) code that prompt users to keep entering names using a loop. If the user does not enter 'q'(without quotes) and if the value entered is NOT null, then the value entered should be added to the array (in my case, names).
If the user enters 'q', the loop should stop, 'q' will not be entered in the array and the list of names should be printed (through the second function in my code).
Here's what I have so far... I can make the code work if I tell the loop to run i<5... it runs 5 times and then it stops. But it fails if i do i < names.length..it causes it say that length is null or not an object (on line 10). That's problem one. And for the life of me, I can't figure out how to add the logic that will run the loop until user enters q.
Please help!
Thank you.
function getNames(){
var names = new Array();
for(i=0;i<names.length;i++){ /*if i do i=0;i<5;i++, the code works; it doesn't with this*/
names[i] = prompt("Enter an item to add to the Name list (enter \'q\' to quit","");
}
printNames(names);
}
function printNames(names) {
for(x=0; x < names.length;x++){
document.write(names[x] + '<br />');
}
}
getNames();
printNames();
I am sure somewhere in your class/book it talks about while loops. So you want to use a while loop if you want them to keep entering without a limit.
while (myCondition===true) {
//do something
}
Now look at your for loop and figure out why it is failing.
for(i=0;i<names.length;i++)
Look at what it is doing:
i = 0
names.length = 0
Is 0 < 0?
Well to start with Problem 1:
Your names array begins with a length property of 0 and so your first for loop doesn't run because 0 is not less than 0.
Which leads to Problem 2:
Again since nothing was entered into your names array your second for loop again does nothing and doesn't execute document.write because the length property of your array is still 0.

Password Strength Meter

I'm trying to create my own JS Password Strength Meter.
It was working before but i didn't like how it worked so I tried using
{score +=10;}
Instead of just:
score++
This is my code:
http://jsfiddle.net/RSq4L/
Best Regards,
Shawn,
Hope someone can help
Multiple issues:
Your passwordStrength() function was not defined in the global scope in the jsFiddle so it wasn't getting called. This is probably an artifact of how you set up the jsFiddle, perhaps not an issue in your real code.
The method of getting the appropriate ratingMsg will not work because you don't have array values for every possible score so many scores will generate an "undefined" ratingMsg.
Your CSS classes are also sparse so there are many score values that they will not match for either and no appropriate CSS class/style will be in effect. If you want a specific class for each rating value, then perhaps you should put the classname in the ratings array so it can be fetched from there along with the ratingsMsg.
For the first issue, in your jsFiddle, you also have to make sure the password processing function is defined in the global scope. The way your jsFiddle is set up, it is not (it's in the onload handler). You can fix this in the jsFiddle by just setting the first drop-down in the upper left to "no wrap (head)".
For the second issue, you are using:
ratingMsg[score]
but, your array is a sparse array not guaranteed to have an entry for most possible scores. You simply can't do it that way because many elements you access will have undefined values which won't give you a meaningful message. For example, if score was 15, you would be accessing ratingMsg[15], but there is no value in that space in the array so you won't get a meaningful rating message.
The solution is to find a different way to select the right message. The simplest way would just be an if/else if/else if statement that would check which range the score is in and set the appropriate msg. There are more elegant table driven ways, but all will involve searching through a data structure to find which two values the current score is between and using that msg.
If you look at this jsFiddle http://jsfiddle.net/jfriend00/dA7XC/, you'll see that your code is getting called, but it only hits values in the array sometimes.
And, here's a rewritten algorithm that finds the appropriate msg no matter what the score show in this fiddle: http://jsfiddle.net/jfriend00/jYcBT/.
It uses a data structure like this:
var ratingMsg = [
0, "Unclassified",
10, "Weak",
20, "Fair",
50, "Better",
60, "Medium",
70, "Good",
90, "Strong"
];
and a for loop like this to get the appropraite ratingMsg:
for (var i = ratingMsg.length - 2 ; i >= 0; i-=2) {
if (score >= ratingMsg[i]) {
msg = ratingMsg[i+1];
break;
}
}
Here you go: http://jsfiddle.net/RSq4L/11/
The first problem is that in your fiddle you have the onLoad option set, so your passwordStrength function is not actually being declared in the global scope. It is being declared inside of the onLoad block that jsFiddle wraps your code with. This causes the page to error out when the keypress handler tries to invoke the function.
You can fix this problem in several different ways:
By explicitly declaring the function as global as per my example above.
By choosing one of jsFiddle's "no wrap" options instead of onLoad.
By dynamically binding your event-handler instead of setting it through the element's onkeydown attribute in the markup.
The second problem is how you are keying your score messages. You have:
var ratingMsg = new Array(0);
ratingMsg[0] = "Unclassified";
ratingMsg[10] = "Weak";
ratingMsg[30] = "Fair";
ratingMsg[50] = "Better";
ratingMsg[60] = "Medium";
ratingMsg[70] = "Good";
ratingMsg[90] = "Strong";
...and you lookup the message by doing ratingMsg[score]. This will only work if the score exactly matches one of your indices. And based upon your math this will not always be the case.
I would suggest doing something like:
ratingMsg = {};
ratingMsg[0] = "Unclassified";
ratingMsg[10] = "Weak";
ratingMsg[30] = "Fair";
ratingMsg[50] = "Better";
ratingMsg[60] = "Medium";
ratingMsg[70] = "Good";
ratingMsg[90] = "Strong";
function closestRating(score) {
var bestKey = 0;
var bestMatch = 100;
for (var key in ratingMsg) {
if (key <= score && score - key < bestMatch) {
bestMatch = score - key;
bestKey = key;
}
}
return ratingMsg[bestKey];
}
On an unrelated note, are you sure you want to be using onkeydown? I think onkeyup would work better.
Your fiddler script had several errors. Here's the corrected one: new script.
You were missing a semicolon here: document.getElementById("passwordDescription").innerHTML = "" + ratingMsg[score] + ""
You forgot to escape '^' on your regular expression
I just wrote this for it:
Jquery Plugin for password strength forcing

Categories