Improving Secure Password Generator - javascript

Simple Password Generator Example:
function randomPassword() {
var chars = "abcdefghijklmnopqrstuvwxyz" +
"ABCDEFGHIJKLMNOP" +
"1234567890" +
"#\#\-!$%^&*()_+|~=`{}\[\]:\";'<>?,.\/",
pass = "",
PL = 10;
for (var x = 0; x < PL; x++) {
var i = Math.floor(Math.random() * chars.length);
pass += chars.charAt(i);
}
return pass;
}
function generate() {
myform.row_password.value = randomPassword();
}
<form name="myform" method="post" action="">
<table width="100%" border="0">
<tr>
<td>Password:</td>
<td>
<input name="row_password" type="text" size="40">
<input type="button" class="button" value="Generate" onClick="generate();" tabindex="2">
</td>
</tr>
</table>
</form>
Improving Functionality Questions
1). Obtaining All Values Within Variable
Taking the base script above, how can I call chars.length and chars.charAt(i) where chars equals all the values within Chars?
var Chars = {};
Chars.abc = "abcdefghijklmnopqrstuvwxyz";
Chars.ABE = "ABCDEFGHIJKLMNOP";
Chars.Num = "1234567890";
Chars.Sym = "#\#\-!$%^&*()_+|~=`{}\[\]:\";'<>?,.\/";
2). Implementing a checkbox system for less advanced password
To generate a less advanced password, such as not including symbox via unchecking a checkbox, how can I make it so only Chars.abc, Chars.ABE, and Chars.Num values are used?
3). Equally Divide Password Length By Chars
Round down (Password length / Chars used ), ie; the example used in this question generates a 10 character password and uses all charecters, therefore there would be a minimum of 2 of each Chars.

The 3rd functionality is missing and will probably be way more sophisticated. But this is a simple solution to the 1st and 2nd ones.
var output = document.getElementsByTagName('output')[0];
var Chars = {};
Chars.length = 16;
Chars.abc = "abcdefghijklmnopqrstuvwxyz";
Chars.ABE = "ABCDEFGHIJKLMNOP";
Chars.Num = "1234567890";
Chars.NumRequired = true;
Chars.Sym = "#\#\-!$%^&*()_+|~=`{}\[\]:\";'<>?,.\/";
var generator = new randomPasswordGenerator(Chars);
var simpleGenerator = new randomPasswordGenerator({
length: 6,
abc: 'abc',
Num: '0'
});
var button = document.getElementsByTagName('button')[0];
button.addEventListener('click', clickFunction);
var checkbox = document.getElementsByTagName('input')[0];
function clickFunction () {
if (checkbox.checked) output.textContent = simpleGenerator.randomPassword();
else output.textContent = generator.randomPassword();
}
function randomPasswordGenerator(opts) {
for(var p in opts) this[p] = opts[p];
this.randomPassword = randomPassword;
}
function randomPassword() {
var chars = (this.abc || "") +
(this.ABE || "") +
(this.Num || "") +
(this.Sym || ""),
pass = [],
PL = this.length;
if (this.NumRequired) {
var r = Math.floor(Math.random() * this.Num.length);
var i = Math.floor(Math.random() * PL);
pass[i] = this.Num[r];
}
for (var x = 0; x < PL; x++) {
if(!pass[x]) {
var i = Math.floor(Math.random() * chars.length);
pass[x] = chars.charAt(i);
}
}
return pass.join('');
}
output {
margin: 12px;
display: block;
border-bottom: 1px solid
}
<button>Generate</button>
<input type="checkbox">Simple
<output></output>

Related

jQuery number format for HTML input number with dynamic decimals

I've seen a lot of similar threads or library but I haven't found one I need.
I have preexisting code with many input[type=number] in the forms. I need to format the number value to local format when form is viewed at first load or when cursor/pointer is out of focus (onblur), and unformat the number to raw input when onfocus or when the form is submitted. The format are dot as separator and comma as decimal. The decimal numbers are dynamic, some don't have decimals, some have 2 or 4, or in other words, the decimal format is only shown when the number has decimal. And when a field doesn't have any value, still displays an empty string ("") not zero (0). A field that has 0 value still displays a 0.
Example:
//Number is 1400.45
//Document ready: 1.400,45
//Onfocus: 1400.45
//Onblur: 1.400,45
//Onsubmit value send by PHP page load: 1400.45
Is there any way to do this or jQuery/javascript library for this?
I don't think there is a library for such a specialized solution you are looking for but you can do it on your own.
That's the idea:
String.prototype.replaceLast = function(find, replace) {
var index = this.lastIndexOf(find);
if (index >= 0) {
return this.substring(0, index) + replace + this.substring(index + find.length);
}
return this.toString();
};
let transformValue = function(value) {
value = parseFloat(value);
value = parseInt(value).toLocaleString() + '.' + parseInt(value.toString().split('.')[1] || '0');
value = value.replace(',', '.');
value = value.replaceLast('.', ',');
return value;
};
let form = document.querySelector('#myForm');
window.addEventListener('load', function() {
let inputs = form.querySelectorAll('input[type="text"]');
for (let i = 0; i < inputs.length; i++) {
let input = inputs[i];
input.value = transformValue(input.value);
input.onfocus = function() {
this.value = this.value.replaceAll('.', '').replace(',', '.');
};
input.onblur = function() {
this.value = transformValue(this.value);
};
}
});
form.onsubmit = function() {
let inputs = form.querySelectorAll('input[type="text"]');
for (let i = 0; i < inputs.length; i++) {
inputs[i].value = inputs[i].value.replaceAll('.', '').replace(',', '.'); }
for (let i = 0; i < inputs.length; i++) {
alert('submitted value ' + inputs[i].value);
}
};
#myForm {
display: flex;
flex-direction: column;
}
#myForm input {
outline: none;
border: 1px solid #000;
border-radius: 3px;
margin: 5px 0;
padding: 3px 7px;
}
<form id="myForm">
<input type="text" value="1400.45">
<input type="text" value="1401.45">
<input type="text" value="1402.45">
<input type="submit">
</form>
The below solution is totally dynamic, as wherever you want to put decimal position.
var num;
$(document).ready(function(){
num=$(".nums").val();
var nstring=num.replace(/\D/g,'');
var total_strings=nstring.length;
totalz=pad("1", (total_strings));
var nums=eval(nstring/totalz);
nums=""+nums+"";
var new_array=nums.split(".");
var val_1=addCommas(new_array[1]);
var narray=new_array[0]+"."+val_1;
$(".nums").val(narray);
});
$(".nums").focus(function(){
var numz=num;
$(".nums").val(numz);
});
$(".nums").blur(function(){
num=$(".nums").val();
var nstring=num.replace(/\D/g,'');
var total_strings=nstring.length;
totalz=pad("1", (total_strings));
var nums=eval(nstring/totalz);
nums=""+nums+"";
var new_array=nums.split(".");
var val_1=addCommas(new_array[1]);
var narray=new_array[0]+"."+val_1;
$(".nums").val(narray);
});
$(".nums").focus(function(){
var numz=num;
$(".nums").val(numz);
});
$(".form1").submit(function(){
var numz2=num;
$(".nums").val(numz2);
$(".form1").submit();
});
function pad (str, max) {
str = str.toString();
return str.length < max ? pad(str+"0", max) : str;
}
function addCommas(nStr) {
nStr += '';
var x = nStr.split('.');
var x1 = x[0];
var x2 = x.length > 1 ? '.' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + ',' + '$2');
}
return x1 + x2;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form class="form1" action="submit.php" method="post">
<input type="text" name="num" class="nums" value="1.40045">
<input type="submit">
</form>

Is there a way to split inserted value for example 1234567890 to 12345 and 67890?

Is there a function that splits the the given string into 2 evenly and place half of each to different textboxes?
I have tried var.split and var.slice
<script>
function display()
{
var myStr = document.getElementbyId("reqnum").value;
var strArray = myStr.split(" ");
// Display array values on page
for(var i = 0; i < strArray.length; i++){
document.write("<p>" + strArray[i] + "</p>");
}
}
the expected should split the no. evenly and would display an error if the numbers are odd.
You can check the length of your input string. If it is odd then display an error.
<input type="text" id="reqnum" >
<input type="button" value="Display" onclick="display()">
<script>
function display()
{
var myStr = document.getElementById("reqnum").value;
if( !myStr || myStr.length % 2 == 1){
document.write("<p>Invalid input</p>");
}else{
var a = parseInt(myStr.substring(0, myStr.length/2));
var b = parseInt(myStr.substring(myStr.length/2, myStr.length));
document.write("<p>" + a + "</p>");
document.write("<p>" + b + "</p>");
document.write("<p> Result after multiplication : " + (a*b) + "</p>");
}
}
</script>
you can convert the numbers to string and then you can do the following.
var num = "1234567890"
var num1
var num2
if (num.length % 2 == 0) {
num1 = num.slice(0, (num.length / 2))
num2 = num.slice((num.length / 2))
} else {
console.log("Number contains odd number of digits")
}
console.log("Num1 " + num1 + " and Num2 " + num2)
use the Slice method, documentation is here.
For your slicing in half:
let half1, half2;
if( myStr.length % 2 == 0 ){
half1 = myStr.slice(0, (myStr.length / 2));
half2 = myStr.slice( (myStr.length / 2), myStr.length );
} else {
// error code
}
function splitToEqual(num){
num = num.toString()
return [num.substring(0, num.length / 2), num.substring(num.length / 2, num.length)]
}
console.log(splitToEqual(1234567890))
Have you tried using slice and length String methods?
Ie.
const string = '1234567890';
const length = string.length;
const res1 = string.slice(0,length/2);
const res2 = string.slice(length/2);
console.log(res1,res2);
Based on your request, I created the following piece of code :-)
Hope it helps.
var inputBox, warning, fBox, sBox;
function inputBoxChanged(e) {
var text = e.currentTarget.value;
if (text.length % 2 != 0) {
warning.innerText = "Value needs to be even sized";
fBox.value = "";
sBox.value = "";
} else {
warning.innerText = "";
var splitPos = text.length / 2;
fBox.value = text.slice(0, splitPos);
sBox.value = text.slice(splitPos, text.length);
}
}
document.addEventListener("DOMContentLoaded", function (e) {
inputBox = document.getElementById("input");
warning = document.getElementById("warning");
fBox = document.getElementById("first");
sBox = document.getElementById("second");
inputBox.addEventListener("change", inputBoxChanged);
});
<html>
<body>
<input id="input" type="text"/>
<span id="warning"></span>
<hr/>
<input id="first" type="text" readonly/>
<input id="second" type="text"readonly/>
</body>
</html>
Use substring() function as
var substring=string.substring(strating_index,end_index);
index will start from 0
var str="1234567890"
var substr=str.substring(0,str.length/2);
var substr2=str.substring(strlength/2,strlength);
$("#ID1").val(substr);
$('#ID2').val(substr2);

How can I create a secret message app using the square code method?

I need to create a secret message app, such that a text:
"If man was meant to stay on the ground, god would have given us roots."
is normalized to:
"ifmanwasmeanttostayonthegroundgodwouldhavegivenusroots"
And the normalised text forms a rectangle (​r x c​) where ​c​ is the number of columns and ​r​ is the number of rows such that ​c >= r​ and ​c - r <= 1​,
So for instance the normalized text is 54 characters long, dictating a rectangle with ​c = 8​ and ​r = 7​:
"ifmanwas"
"meanttos"
"tayonthe"
"groundgo"
"dwouldha"
"vegivenu"
"sroots "
Then the coded message is obtained by reading down the columns going left to right
"imtgdvsfearwermayoogoanouuiontnnlvtwttddesaohghnsseoau"
and further split to
"imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn sseoau"
The resulting cypher text for a non perfect rectangle can only have a single whitespace for the last rows.
"imtgdvs"
"fearwer"
"mayoogo"
"anouuio"
"ntnnlvt"
"wttddes"
"aohghn "
"sseoau "
This what I have done so far, I could only get my normalised text, but I am doing something wrong to convert it to a rectangle and to get a cypher text out of it.
const output = document.querySelector('#encoded_rectangle');
const encodedChunks = document.querySelector('#encoded_chunks');
const text = document.querySelector('#normalized_text');
const string = document.querySelector('#message');
const error = document.querySelector('#alert');
const encodeMessage = () => {
let message = string.value;
function wordCount() {
return message.split(" ").length;
}
if (wordCount < 2 || message.length < 50) {
error.innerHTML = "Invalid message, Input more than one word and at Least 50 characters!";
return false;
}
function normaliseMessage() {
return message.replace(/[^a-zA-Z0-9]/g, "").toLowerCase();
}
function rectangleSize() {
return Math.ceil(Math.sqrt(normaliseMessage.length));
}
function splitRegEx() {
return new RegExp(".{1," + rectangleSize + "}", "g");
}
function plaintextSegments() {
return normaliseMessage.match(splitRegEx);
}
function ciphertext() {
var columns = [],
currentLetter, currentSegment;
var i, j;
for (let i = 0; i < rectangleSize; i++) {
columns.push([]);
}
for (i = 0; i < plaintextSegments.length; i++) {
currentSegment = plaintextSegments[i];
for (j = 0; j < columns.length; j++) {
currentLetter = currentSegment[j];
columns[j].push(currentLetter);
}
}
for (i = 0; i < columns.length; i++) {
columns[i] = columns[i].join("");
}
return columns.join("");
}
function normalizeCipherText() {
return ciphertext.match(splitRegEx).join(" ");
}
text.innerHTML = plaintextSegments();
encodedChunks.innerHTML = ciphertext();
output.innerHTML = normalizeCipherText();
}
<form>
<input type="text" placeholder="Type your secret message" id="message">
<p id="alert"></p>
<button type="button" class="button" onclick="encodeMessage()">Encode message</button>
</form>
<div class="box">
<h3>Normalised Text</h3>
<p id="normalized_text"></p>
</div>
<div class="box">
<h3>Encoded Chunks</h3>
<p id="encoded_chunks">
</p>
</div>
<div class="box">
<h3>Encoded Rectangle</h3>
<p id="encoded_rectangle">
</p>
</div>
Most of your code is constructed of very short methods.
Usually I'd consider a good practice, but in this case I think it just made the code less readable.
Additionally, I have to say that the HTML part wasn't necessary in terms of solving the issue - which was clearly Javascript/algorithm related.
This is my solution, which can be modified to match your context:
const input = "If man was meant to stay on the ground, god would have given us roots.";
const normalizedInput = input.replace(/[^\w]/g, "").toLowerCase();
const length = normalizedInput.length;
const cols = Math.ceil(Math.sqrt(length));
const rows = Math.ceil(length / cols);
var cypherText = "";
for (let i = 0; i < cols; i ++) {
for (let j = i; j < normalizedInput.length; j += cols) {
cypherText += normalizedInput[j];
}
cypherText += '\n';
}
console.log(cypherText);
This is what I came up with
const output = document.querySelector('#encoded_rectangle');
const encodedChunks = document.querySelector('#encoded_chunks');
const text = document.querySelector('#normalized_text');
const string = document.querySelector('#message');
const error = document.querySelector('#alert');
const encodeMessage = () => {
let message = string.value;
var normalisedText = message.replace(/[^a-zA-Z0-9]/g, "");
var textCount = normalisedText.length;
if (textCount < 50) {
console.log("Invalid message, Input more than one word and at Least 50 characters!");
return false;
}
var higest = Math.ceil(Math.sqrt(textCount));
var lowest = Math.ceil(textCount/higest);
var rect = [];
var coded = [];
var innerObj = {};
var resulting = "";
rect = rectangleSize(higest,lowest,normalisedText);
//read text from top-down i hotago!!!
coded = readFromTopDown(rect, higest);
coded.forEach(co => {
resulting += co.trim();
});
//nwa idi sharp, nice logic
console.log("Normalized: " + normalisedText);
console.log("Count: " + textCount);
console.log(rect);
console.log(coded);
console.log("Resulting: " + resulting);
function rectangleSize(higest, lowest, normalise) {
var rect = [];
var startIndex = 0;
for(var i = 0; i < lowest; i++){
if(i !== 0)
startIndex += higest;
if(normalise.substring(startIndex, startIndex + higest).length == higest){
rect.push(normalise.substring(startIndex, startIndex + higest))
}else{
//get the remainder as spaces
var spaces = higest - normalise.substring(startIndex, startIndex + higest).length;
var textI = normalise.substring(startIndex, startIndex + higest);
var str = textI + new Array(spaces + 1).join(' ');
rect.push(str);
}
}
return rect;
}
function readFromTopDown(rect, higest) {
var coded = [];
for(var i = 0; i < higest; i++){
var textMain = "";
rect.forEach(re => {
textMain += re.substring(i, i+1);
});
coded.push(textMain);
}
return coded;
}
}
<form>
<input type="text" placeholder="Type your secret message" id="message">
<p id="alert"></p>
<button type="button" class="button" onclick="encodeMessage()">Encode message</button>
</form>
<div class="box">
<h3>Normalised Text</h3>
<p id="normalized_text"></p>
</div>
<div class="box">
<h3>Encoded Chunks</h3>
<p id="encoded_chunks"></p>
</div>
<div class="box">
<h3>Encoded Rectangle</h3>
<p id="encoded_rectangle"></p>
</div>
Try and see

Make calculation based on information provided

I am building a website and I want to do calculations based on information provided. I obviously need to have information provided in two out of the three fields to calculate the third's value.
The three fields are:
Price Per Gallon
Gallons Bought
Total Sale
I obviously know that I can calculate the amount of gas bought by dividing the Total Sale amount by the Price Per Gallon.
However I want to calculate based on whatever two fields are entered. I am trying to find out the best way to do this.
I know this much:
Check to see which fields are empty
Determine which type of calculation to make
Here is what I have so far:
<form>
<input type="number" id="totalSale" placeholder="Total Sale Amount" class="calculate" />
<input type="number" id="gallonPrice" placeholder="Price Per Gallon" class="calculate" />
<input type="number" id="gallons" placeholder="Gallons" class="calculate" />
</form>
<script>
var e = document.getElementsByClassName("calculate");
function calc(){
var sale_amt = document.getElementById("totalSale");
var ppg = document.getElementById("gallonPrice");
var gallons = document.getElementById("gallons");
if (sale_amt || ppg !== null) {
var calc_gallons = sale_amt.value / ppg.value;
gallons.value = calc_gallons.toFixed(3);
}
}
for (var i = 0; i < e.length; i++) {
e[i].addEventListener('keyup', calc, false);
}
</script>
the logic should take into consideration which element is currently being entered (that will be this in calc). Also, you need to take into consideration what happens when all three have values, and you change one ... which of the other two should be changed?
See if this works for you
var sale_amt = document.getElementById("totalSale");
var ppg = document.getElementById("gallonPrice");
var gallons = document.getElementById("gallons");
function calc(){
var els = [sale_amt, ppg, gallons];
var values = [sale_amt.value, ppg.value, gallons.value];
var disabledElement = els.find(e=>e.disabled);
var numValues = els.filter(e => e.value !== '' && !e.disabled).length;
var calc_gallons = function() {
gallons.value = (values[0] / values[1]).toFixed(3);
};
var calc_ppg = function() {
ppg.value = (values[0] / values[2]).toFixed(3);
};
var calc_sale = function() {
sale_amt.value = (values[1] * values[2]).toFixed(2);
};
if (numValues < 3) {
if (numValues == 1 && disabledElement) {
disabledElement.disabled = false;
disabledElement.value = '';
disabledElement = null;
}
els.forEach(e => e.disabled = e == disabledElement || (numValues == 2 && e.value === ''));
}
disabledElement = els.find(e=>e.disabled);
switch((disabledElement && disabledElement.id) || '') {
case 'totalSale':
calc_sale();
break;
case 'gallonPrice':
calc_ppg();
break;
case 'gallons':
calc_gallons();
break;
}
}
var e = document.getElementsByClassName("calculate");
for (var i = 0; i < e.length; i++) {
e[i].addEventListener('keyup', calc, false);
e[i].addEventListener('change', calc, false);
}

Unable to call function within jQuery

I am trying to call a function in this javascript code. My code needs to check for whether the user selects var num, var letters and var symbols to be true or false. In the code, I preset the values but I still search the object choices for the variables that are true and push it into the array choices_made. However, since I need to randomly choose the order in which the num, letters and symbols appear, I randomly choose the class based on the Math.random(). However, it doesn't show me the alert(jumbled_result) afterwards.
http://jsfiddle.net/bdaxtv2g/1/
HTML
<input id="num" type="text" placeholder="Enter desired length">
<br/><br/>
<input id="press" type="button" value="jumble it up">
JS
$(document).ready(function(){
var fns={};
$('#press').click(function(){
var length = parseInt($('#num').val());
var num = true;
var letters = true;
var symbols = false;
gen(length, num, letters, symbols);
});
function gen(len, num, letters, sym){
var choices = {
1:num,
2:letters,
3:sym
};
var choice_made = ['0'];
var choice = 0;
var jumbled_result = '';
for(x in choices){
if(choices[x]==true){
choice_made.push(x);
}
}
for(i=0;i<len;i++){
var funName = 'choice';
choice = Math.round(Math.random() * (choice_made.length-1));
funName += choice_made[choice];
jumbled_result = fns[funName](jumbled_result);
}
alert(jumbled_result);
}
fns.choice0 = function choice0(jumbled_result){
var numbers = '0123456789';
return jumbled_result += numbers.charAt(Math.round(Math.random() * numbers.length));
}
fns.choice1 = function choice1(jumbled_result) {
var alpha = 'abcdefghijklmnopqrstuvwxyz';
return jumbled_result += alpha.charAt(Math.round(Math.random() * alpha.length));
}
});
You never declare functions within document.ready of jQuery. The functions should be declared during the first run(unless in special cases).
Here is a working code made out of your code. What I have done is just removed your functions out of document.ready event.
$(document).ready(function() {
$('#press').click(function() {
var length = parseInt($('#num').val());
var num = true;
var letters = true;
var symbols = false;
gen(length, num, letters, symbols);
});
});
var fns = {};
function gen(len, num, letters, sym) {
var choices = {
1: num,
2: letters,
3: sym
};
var choice_made = ['0'];
var choice = 0;
var jumbled_result = '';
for (x in choices) {
if (choices[x] == true) {
choice_made.push(x);
}
}
for (i = 0; i < len; i++) {
var funName = 'choice';
choice = Math.round(Math.random() * (choice_made.length - 1));
funName += choice_made[choice];
jumbled_result = fns[funName](jumbled_result);
}
alert(jumbled_result);
}
fns.choice0 = function choice0(jumbled_result) {
var numbers = '0123456789';
return jumbled_result += numbers.charAt(Math.round(Math.random() * numbers.length));
}
fns.choice1 = function choice1(jumbled_result) {
var alpha = 'abcdefghijklmnopqrstuvwxyz';
return jumbled_result += alpha.charAt(Math.round(Math.random() * alpha.length));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="num" type="text" placeholder="Enter desired length">
<br/>
<br/>
<input id="press" type="button" value="jumble it up">
Its because of the way the object choices have been intitialized.. Try this..
var choices = {
0:num,
1:letters,
2:sym
};
And also
var choice_made = [];
JS fiddle link : http://jsfiddle.net/8dw7nvr7/2/

Categories

Resources