I'm trying to build a password generator which creates passwords conforming to:
Minimum 8 characters in length, Maximum 40 characters in length
Must contain at least 1 uppercase, lowercase, number and symbol
I'm avoiding Math.random out of choice, I prefer the crypto option.
I've been through loads of articles to try and get this working, but I'm having the following issues:
Random spaces seem to occur in the output string, often on the end.
Output values are sometimes not conforming to the min 8 char rule.
I realize I probably have far too many additional if statements double checking things, but I'm struggling to see where it's going wrong.
This is to go into another system, so I'm creating it as modular and functional as possible. Apologies for the large snippet below, I couldn't get it working in jsfiddle.
function cryptoPassword(){
var minFieldNum = 8; //Minimum char size of desired output
var maxFieldNum = 40; //X defines their fields as 40 as the max_length
var outputValue = ''; //Output for field/overall function
var fieldRandom = getRandomInt(minFieldNum, maxFieldNum); //Generate length of password
if (fieldRandom < minFieldNum || fieldRandom > maxFieldNum) {
fieldRandom = getRandomInt(minFieldNum, maxFieldNum); //Regenerate if length doesn't conform - Not working?
}
else {
for (i = 0; outputValue.length < fieldRandom; i++) {
var mask = getRandomMask(); //Get mask selection
var randomChar = mask.charAt(getRandomInt(0,mask.length)); //Pick random char in mask
if (randomChar == " ") { //I don't know where the spaces come from
var randomChar = mask.charAt(getRandomInt(0,mask.length)); //Pick random char in mask
}
outputValue += randomChar; //Add to output
}
if (passwordChecker(outputValue, minFieldNum)) {
return outputValue + " " + passwordChecker(outputValue, minFieldNum);
}
else {
return cryptoPassword();
}
}
}
function getRandomInt(min, max) {
var byteArray = new Uint8Array(1);
window.crypto.getRandomValues(byteArray);
var range = (max - min + 1);
return min + (byteArray[0] % range);
}
function getRandomMask() {
var maskLcaseChar = 'abcdefghijklmnopqrstuvwxyz';
var maskUcaseChar = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var maskNumeric = '0123456789';
var maskSpecial = '!"$%^&*(){}[];#,./:#~<>?|_+-=';
var maskRandomNo = getRandomInt(0, 3);
var selectMask = [maskLcaseChar, maskUcaseChar, maskNumeric, maskSpecial];
return selectMask[maskRandomNo];
}
function passwordChecker(output, minSize){
var checkChars = '!"$%^&*(){}[];#,./:#~<>?|_+-=';
if (output.length < minSize){
return false
}
else if((output.toUpperCase() != output) && (output.toLowerCase() != output)) {
for (var i = 0; i < output.length; i++) {
if (checkChars.indexOf(output.charAt(i)) != -1) {
return true;
}
}
}
return false;
}
So the issue seems to have been with the getRandomInt function which would return an int between 0 and the length of the mask. As you're dealing with arrays you really want it to be between 0 and length of array -1.
You were getting empty strings back from the charAt function as you were asking for a position out side the array.
I've fixed that and also optimised the generating section a bit. It always adds one char from each of the masks, then takes them randomly after that. I then shuffle the string, moving the initial 4 around. It's not using crypto to shuffle but I don't think it's necessary there.
function cryptoPassword(){
var maskLcaseChar = 'abcdefghijklmnopqrstuvwxyz';
var maskUcaseChar = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var maskNumeric = '0123456789';
var maskSpecial = '!"$%^&*(){}[];#,./:#~<>?|_+-=';
var maskAll = maskLcaseChar + maskUcaseChar + maskNumeric + maskSpecial;
var mask = '';
var minFieldNum = 8; //Minimum char size of desired output
var maxFieldNum = 40; //X defines their fields as 40 as the max_length
var outputValue = ''; //Output for field/overall function
var fieldRandom = getRandomInt(minFieldNum, maxFieldNum); //Generate length of password
if (fieldRandom < minFieldNum || fieldRandom > maxFieldNum) {
console.log("error length", fieldRandom)
fieldRandom = getRandomInt(minFieldNum, maxFieldNum); //Regenerate if length doesn't conform - Not working?
}
else {
var randomChar = '';
var rnd;
randomChar = maskLcaseChar.charAt(getRandomInt(0,maskLcaseChar.length)); //Pick random lower case
outputValue += randomChar; //Add to output
randomChar = maskUcaseChar.charAt(getRandomInt(0,maskUcaseChar.length)); //Pick random upper case
outputValue += randomChar; //Add to output
randomChar = maskNumeric.charAt(getRandomInt(0,maskNumeric.length)); //Pick random numeric
outputValue += randomChar; //Add to output
randomChar = maskSpecial.charAt(getRandomInt(0,maskSpecial.length)); //Pick random special
outputValue += randomChar; //Add to output
mask = maskAll;
for (var i = 3; i < fieldRandom; i++) {
randomChar = mask.charAt(getRandomInt(0,mask.length)); //Pick random char
outputValue += randomChar;
}
outputValue = shuffleString(outputValue); //shuffle output
if (passwordChecker(outputValue, minFieldNum)) {
return outputValue + passwordChecker(outputValue, minFieldNum);
}
else {
console.log("error password", outputValue);
}
}
}
function shuffleString(inputString) {
var array = inputString.split('');
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array.join('');
}
function getRandomInt(min, max) {
var byteArray = new Uint8Array(1);
window.crypto.getRandomValues(byteArray);
var range = (max - min);
var output = min + (byteArray[0] % range);
return output
}
function passwordChecker(output, minSize){
var checkChars = '!"$%^&*(){}[];#,./:#~<>?|_+-=';
if (output.length < minSize){
console.log("too short")
return false
}
else if((output.toUpperCase() != output) && (output.toLowerCase() != output)) {
for (var i = 0; i < output.length; i++) {
if (checkChars.indexOf(output.charAt(i)) != -1) {
if(output.indexOf(' ') === -1){
return true;
}
}
}
}
console.log("doesn't meet standards")
return false;
}
for(j=0; j<10000; j++){
cryptoPassword()
}
console.log("done")
I've added a quick test at the bottom. It'll generate 10,000 passwords. It'll only output them to console if they fail your test. You'll probably want to remove that and some of the console.logs and tidy it up a bit.
Related
I created a function in javascript to generate a random string with a certain length in either uppercase/lowercase or both.
function randomString(max, option) {
var rNum = [];
if (option.toLowerCase() === "lowercase") {
for (let i = 0; i < max; i++) {
var randomNumber = Math.floor(Math.random() * (122 - 97) + 97);
rNum.push(randomNumber);
}
} else if (option.toLowerCase() === "uppercase") {
for (let i = 0; i < max; i++) {
var randomNumber = Math.floor(Math.random() * (90 - 65) + 65);
rNum.push(randomNumber);
}
} else if (option.toLowerCase() === "both") {
for (let i = 0; i < max; i++) {
var n = Math.floor(Math.random() * (122 - 65) + 65);
while ([91, 92, 93, 94, 95, 96].includes(n)) {
//If the random number is between 90 and 97 then we keep generating new numbers:
n = Math.floor(Math.random() * (122 - 65) + 65);
}
rNum.push(n);
}
} else {
return "Second parameter not valid, please type 'lowercase','uppercase' or 'both'";
}
var word = "";
for (let i = 0; i < rNum.length; i++) {
var letter = String.fromCharCode(rNum[i]);
word += letter;
}
return word;
}
Now I wanted to create a second function that given any string from the user, it checks whether that word appears in the randomly generated string.
I started it and honestly I simply have no idea how to do it. How do I check where in that long string there is indeed the word which I don't know how long it is. I guess it can see if it does exist or not, but how do i find its position? I tried using array.indexOf(userString), but it only returns the first time it appears.
function findWordsByChance(letters) {
var myString = randomString(999999, "both");
var splited = myString.split("");
if (splited.includes(letters)) {
console.log("this combination exists");
} else {
console.log("it doesnt");
}
for (let i = 1; i < splited.length - 1; i++) {
//check where it is (??)
}
}
findWordsByChance("Hi");
I'm still quite new to programming, so give me a break if I made any stupid mistakes :)
btw, if you guys got any tips on how to do something I already did but in a more efficient way, I'd appreciate.
indexOf accepts a second parameter which defines a start offset, so you can use this to loop through and find every occurrence. You just need to make the start point immediately past the last occurrence for each iteration. Here's how I'd write the function:
function indexOfAll(needle, haystack) {
var indices = [];
var index = 0;
while ((index = haystack.indexOf(needle, index)) > -1) {
indices.push(index);
index += needle.length;
}
return indices;
}
console.log(indexOfAll("oat", "goat in a boat"));
...but this may be easier for you to read:
function indexOfAll(needle, haystack) {
var indices = [];
var offset = 0;
while (haystack.indexOf(needle, offset) > -1) {
var indexOfThisOccurrence = haystack.indexOf(needle, offset);
indices.push(indexOfThisOccurrence);
offset = indexOfThisOccurrence + needle.length;
}
return indices;
}
console.log(indexOfAll("ug", "slug in a mug"));
You can use the simple .match() function in javascript to find a string in another string.
var myString = randomString(100, "both");
// myString = "fAuqxBfkXprhvRqOGLPmTiFbhrZtjXXMFwircAGBBtIkiDbGHPvYymMlabJyeAKUtIYNedUpNPlaeEcjIsSeEtOUriHTuCtbpNZX"
var result = myString.match('rZtjX');
// result[0] is your search string...the "letters" value
// result[1] is where the string was found
// If you want to get all occurrences where the search string was found you can use the function below.
findOccurrences = (needle, haystack) => {
const pieces = haystack.split(needle);
if (!pieces.length) {
return console.log('No Matches');
}
let index = 0;
pieces.forEach((piece) => {
index += piece.length;
console.log(needle, ' found at ', index);
index += needle.length;
});
}
findOccurrences('LPmT', myString);
LPmT found at 17
LPmT found at 47
LPmT found at 81
LPmT found at 99
LPmT found at 112
You could turn their input into a regex.
const inputRegex = new RegExp(input, 'g')
Then you could use string.matchAll() to get all instances of matches.
const matches = randomLetters.matchAll(inputRegex)
But that gives you an iterator. To have it as an array, you'd do this instead:
const matches = [...randomLetters.matchAll(inputRegex)]
Now, each item in matches is an object with a key index referring to its position on the string.
You can learn more at MDN.
I have a problem I am sitting on for the past few days.
I want to write an optimal (in JS) program for verifying if a number is a Palindrome.
My current approach:
function isPalidrom2(pali){
//MOST time consuming call - I am splitting the digit into char array.
var digits = (""+pali).split("");
//To get the length of it.
var size = digits.length;
var isPali = true;
for(var i = 0; i<Math.floor(size/2); i++){
//I am comparing digits (first vs last, second vs last-1, etc.) one by one, if ANY of the pars is not correct I am breaking the loop.
if(parseInt(digits[i]) != parseInt(digits[size-i-1])){
isPali = false;
break;
}
}
return isPali;
}
It's not optimal. The biggest amount of time I am waisting is the change from INT to STRING.
And I am out of ideas
- I tried to understand the BIT operators but I can't.
- I tried to google and look for alternative approaches - but I can't find anything.
- I tried to play with different algorithms - but this one is the fastest I was able to apply.
So in short - my question is:
"how can I make it faster?"
EDIT:
So the task I want to solve:
Find all of the prime numbers within the range of all five digit numbers.
Among all of the multiplies (i*j) they are between them, find the most significant palindrome.
My current approach:
function isPrime(number){
var prime = true;
var i
for(i = 2; i<= number/2; i++){
if((number%i)==0){
prime = false;
break;
}
}
return prime;
}
function get5DigitPrimeNr(){
var a5DigitsPrime = [];
var i;
for(i = 10000; i<100000; i++){
if(isPrime(i)){
a5DigitsPrime.push(i)
}
}
return a5DigitsPrime;
}
function isPalidrom(pali){
var digits = (""+pali).split("");
//we check if first and last are the same - if true, we can progress
size = digits.length;
return
(digits[0]==digits[size-1]) &&
(parseInt(digits.slice(1, Math.floor(size/2)).join("")) ==
parseInt(digits.reverse().slice(1, Math.floor(size/2)).join("")))
}
function isPalidrom2_48s(str) {
var str = str.toString();
const lower = str.substr(0, Math.floor(str.length / 2));
const upper = str.substr(Math.ceil(str.length / 2));
return lower.split("").reverse().join("") === upper;
}
function isPalidrom_22s(pali){
var digits = (""+pali).split("");
var size = digits.length;
for(var i = 0; i<Math.floor(size/2); i++){
//console.log("I am comparing: "+i+", and "+(size-i-1)+" elements in array")
//console.log("I am comparing digit: "+digits[i]+", and "+digits[(size-i-1)]+"")
if(digits[i] !== digits[size-i-1]){
//console.log('nie sa rowne, koniec')
return false;
}
}
return true;
}
function isPalidrom2_80s(pali){
return parseInt(pali) == parseInt((""+pali).split("").reverse().join(""))
}
function runme(){
var prime5digits = get5DigitPrimeNr();
var size = prime5digits.length;
var max = 0;
var message = "";
for(var i = 0; i<size; i++){
for(var j = 0; j<size; j++){
var nr = prime5digits[i]*prime5digits[j];
if(nr>max && isPalidrom2(nr)){
max = nr;
message = 'biggest palidrome nr: '+nr+', made from numbers: '+prime5digits[i]+' x '+prime5digits[j];
}
}
}
console.log(message)
}
function timeMe(){
var t0 = performance.now();
runme();
var t1 = performance.now();
console.log("Function took " + millisToMinutesAndSeconds(t1 - t0) + " s to find the perfect palindrom.")
}
//helper functons:
function millisToMinutesAndSeconds(millis) {
var minutes = Math.floor(millis / 60000);
var seconds = ((millis % 60000) / 1000).toFixed(0);
return minutes + ":" + (seconds < 10 ? '0' : '') + seconds;
}
To keep the spirit of you code, you could exit the loop with return instead of break and use the string directly without converting to an array. Strings have, as arrays, the possibility of an access single character with an index.
function isPalidrom2(value) {
var digits = value.toString(),
length = digits.length,
i, l;
for (i = 0, l = length >> 1; i < l; i++) {
if (digits[i] !== digits[length - i - 1]) {
return false;
}
}
return true;
}
console.log(isPalidrom2(1));
console.log(isPalidrom2(12));
console.log(isPalidrom2(1221));
console.log(isPalidrom2(123));
The fastest is probably to rely on javascripts native methods:
function isPalindrome(str) {
const lower = str.substr(0, Math.floor(str.length / 2));
const upper = str.substr(Math.ceil(str.length / 2));
return lower.split("").reverse().join("") === upper;
}
Or leave away all unneccessary conversions from your code:
function isPlaindrome(str) {
const half = str.length / 2;
for(var i = 0; i < half; i++)
if(str[i] !== str[str.length - i - 1])
return false;
return true;
}
If you're trying to speed things up, you could shave a few more seconds off by optimising your isPrime(n) function.
You don't need to check every factor, only the prime factors less than sqrt(n)
If you check every number from 2 to 99999 in ascending order, you can store the results as you go, so you don't need to keep re-calculating the list of previous primes
Something like this:
var savedPrimes = [2]
function isPrime(n){
// call this method with increasing values of n (starting at 2), saving primes as we go,
// so we can safely assume that savedPrimes contains all primes less than n
for(var i=0; i<savedPrimes.length; i++)
{
var f = savedPrimes[i];
if ((n % f) == 0)
return false; // found a factor
if (f*f>=n)
break; // stop checking after f >= sqrt(n)
}
// no prime factors - we found a new prime
savedPrimes.push(n);
return true;
}
function get5DigitPrimeNr(){
var a5DigitsPrime = [];
var i;
// first find all the primes less than 10000
for(i = 3; i<10000; i++){
isPrime(i);
}
// now find (and keep) the rest of the primes up to 99999
for(i = 10000; i<100000; i++){
if(isPrime(i)){
a5DigitsPrime.push(i)
}
}
return a5DigitsPrime;
}
EDIT - when I run your code with this method, I get a time of 10 sec
Code :
There are multiple methods that you can use (dunno if they are optimal) :
Palindrom = _ => (_=''+_) === [..._].sort(_=>1).join``
Some more :
let isPalindrome = __ => (_=(__=__+'').length)==0||_==1?!0:__[0]==__.slice(-1)?isPalindrome(__.slice(1,-1)):!1
let isPalindrome = (s,i) => (i=i||0)<0||i>=(s=''+s).length>>1||s[i]==s[s.length-1-i]&&isPalindrome(s,++i);
let isPalindrome = (str) => {
var len = ~~((str=str+'').length / 2);
for (var i = 0; i < len; i++)
if (str[i] !== str[str.length - i - 1])
return false;
return true;
}
Updated now takes numbers as input
I am trying to divide my string in 2 lines if string is greater than 15 characters, so i am finding a space after 15 char and putting /n to string so that when var gets printed it should get printed in 2 lines.
following is my JavaScript code. its not working, please if anyone can help.
Thankyou
var name = row.product_name;
var val = 15;
var output;
var flag = false;
console.log(name[0]);
for(i=0; i<row.product_name.length; i++)
{
if(i > val)
{
if(name[i] == ' ')
{
name[i] = "/n";
flag = true;
}
}
if(flag)
{
val = val + 15;
flag = false;
}
}
this can't work because javascript strings are immutable, so you can't reassign name[i]. You have to use replace, slice, split, or other operations on the whole string
var myString = "jsdjposjgiohg squg oiq oih osqdh uh hsquv hup h opsdqh voph";
myStringA=myString.split(" ");
var newString="";
var n=0;
for (var i=0;i<myStringA.length;i++){
n+=myStringA[i].length;
if (n>15){
n=0;
newString+=myStringA[i]+"\n";
}else{
newString+=myStringA[i]+" ";
}
}
console.log(newString);
Strings are immutable in javascript so you need to put the changes in a new variable
Also the newline character is \n not /n
var name = row.product_name;
var val = 15;
var output = "";
var flag = false;
console.log(name[0]);
for(i=0; i<row.product_name.length; i++)
{
output += name[i]
if(i > val)
{
if(name[i] == ' ')
{
output[i] = "\n";
flag = true;
}
}
if(flag)
{
val = val + 15;
flag = false;
}
}
Having an issue figuring out how to get this solved, and I've searched and looked for answers, but they don't resemble what I'm looking for.
This is beginner stuff, I realize but any help would be highly appreciated.
The code below was given by my teacher and it works for creating one random number. For the life of me I can't figure out how to make this create 100 random numbers and make a 10 x 10 square of them.
eg. 5468 2367 1587 2587 2310 9802 0154 8753 4965 2571
3249 3248 2158 4659 1321 1278 9871 0123 4654 4587
etc. for 10 rows.
<div id="answer"></div>
<script type="text/javascript">
function giveValues() {
var length, zeroes;
var number = Math.round((Math.random() * 9999));
// toString()-method and lenght to set amount of digts
zeroes = 4 - number.toString().length;
for (var j = 1; j <= zeroes; j++) {
number = "0" + number;
}
return number;
}
document.getElementById("answer").innerHTML = giveValues();
I also know that there is if (j % nameofvar == 0) { for making a new line, but am unable to make that work.
Considering that you haven't learned arrays yet, try the following as I think it's best inline with what you're looking for. Here is a Plunker as well http://plnkr.co/edit/LltYPtSfR9Ndo46kYmVN?p=preview.
<div id="answer"></div>
<script>
function giveValues() {
var length, zeroes;
var number = Math.round((Math.random() * 9999));
// toString()-method and lenght to set amount of digts
zeroes = 4 - number.toString().length;
for (var j = 1; j <= zeroes; j++) {
number = "0" + number;
}
return number;
}
var columns = 10;
var total = 100;
var bigString = "";
for (var i=0; i<total; i++) {
if (i != 0 && i % columns == 0) {
bigString += "<br/>";
}
bigString += giveValues(i).toString() + " ";
}
var answer = document.getElementById("answer");
answer.innerHTML = bigString;
</script>
Most basic way:
function lpad(number) {
while (number.toString().length < 4) {
number = "0"+number;
}
return number;
}
var max = 9999;
var matrix = [];
var size = 10;
for (var i = 0; i < size * size; i++) {
if (i % size === 0) {
matrix.push([]);
}
var number = lpad(Math.ceil(Math.random() * max));
matrix[matrix.length - 1].push(number);
}
document.getElementById("answer").innerHTML = matrix.join("<br />");
<div id = "answer"></div>
Using arrays is more effective, but you can also simply concatenate too.
You could just generate a large random number, and then limit it to 4 digits.
Try this:
function giveValues() {
var number = Math.round((Math.random() * 999999999));
return number.toString().substr(0, 4);
}
var arr = [];
for(var i = 0; i < 10; i++){
arr.push([giveValues(), giveValues(), giveValues(), giveValues(), giveValues(), giveValues(), giveValues(), giveValues(), giveValues(), giveValues()]);
}
document.getElementById("answer").innerHTML = arr.join(' <br/>').replace(/,/g,' ');
https://jsfiddle.net/moshekarmel1/34spm4hh/
so I know this questing has been asked, but all the answers that were given are already known to me. I don't want to make a variable of all the posible numbers (that was always the answer). So to go to the question, I want to make a random number generator, that will generate me 7 numbers, that must not be the same. For example, I get random numbers:
"5,16,12,5,21,37,2" ... But I don't want the number 5 to be used again, so I want different numbers. I made a code for the generation, but I can not think of any good method/way to do this. I was thinking that maybe check if the number is already in array and if it is, then generate another number, but as I'm amateur in JavaScript, I don't know how to do this. So here is my JavaScript code:
// JavaScript Document
function TableOn()
{
document.write("<table border='1'>");
}
function TableOff()
{
document.write("</table>");
}
function RandNum()
{
var n = new Array();
for(var i=0;i<7;i++)
{
n[i] = Math.round((1+(Math.random()*40)));
}
TableOn();
for(var c=0;c<7;c=c+1)
{
document.write("<tr><td>"+n[c]+"</td></tr>");
}
TableOff();
}
In HTML I just have a button, that is onclick="RandNum()" ... Pardon for my English.
I would do it like this:
var nums = [], numsLen = 5, maxNum = 100, num;
while (nums.length < numsLen) {
num = Math.round(Math.random() * maxNum);
if (nums.indexOf(num) === -1) {
nums.push(num);
}
}
This generates an array with 5 random numbers in the range 0..100.
(numsLen cannot be greater than maxNum.)
These commands can be used to check if a value is/is not in your array:
if ( !!~n.indexOf(someVal) ) {
// someVal is in array "n"
}
if ( !~n.indexOf(someVal) ) {
// someVal is not in array "n"
}
I'd use a string, storing the generated random numbers with a divider. Then check if the newly generated number is in that string.
Something like this
generated = "";
for(var i=0;i<7;i++)
{
generate = Math.round((1+(Math.random()*40))); //generate = 5
while (generated.indexOf("[" + generate + "]") != -1) { //checking if the [5] is already in the generated string, and loop until it's a different number
generate = Math.round((1+(Math.random()*40))); //get a new random number
}
generated += "[" + generate + "]";
n[i] = generate;
}
or you can take another longer approach
for(var i=0;i<7;i++)
{
repeated = true;
while (repeated) {
repeated = false;
generate = Math.round((1+(Math.random()*40)));
for (var a=0; a < i, a++) {
if (generate == n[a]) { repeated = true; }
}
}
n[i] = generate;
}
Here's a function to generate an array of n unrepeated random numbers in [min, max):
function rands(n, min, max) {
var range = max - min;
if (range < n)
throw new RangeError("Specified number range smaller than count requested");
function shuffle() {
var deck = [], p, t;
for (var i = 0; i < range; ++i)
deck[i] = i + min;
for (i = range - 1; i > 0; --i) {
p = Math.floor(Math.random() * i);
t = deck[i];
deck[i] = deck[p];
deck[p] = t;
}
return deck.slice(0, n);
}
function find() {
var used = {}, rv = [], r;
while (rv.length < n) {
r = Math.floor(Math.random() * range + min);
if (!used[r]) {
used[r] = true;
rv.push(r);
}
}
return rv;
}
return range < 3 * n ? shuffle() : find();
}
This code checks the range of possible values and compares it to the number of random values requested. If the range is less than three times the number of values requested, the code uses the shuffle to avoid the terrible performance of the lookup approach. If the range is large, however, the lookup approach is used instead.
Not sure if OP's requirement of non-repeating is really needed, but here's a fiddle of something that could work if your number range isn't too big:
http://jsfiddle.net/6rEDV/1/
function range(start, end, step) {
if (typeof step === 'undefined') {
step = 1;
}
if (typeof start === 'undefined' || typeof end === 'undefined') {
throw TypeError('Must have start and end');
}
var ret = [];
for (var i = start; i <= end; i += step) {
ret.push(i);
}
return ret;
};
// source: http://stackoverflow.com/a/6274381/520857
function shuffle(o) { //v1.0
for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
return o;
};
function getNonRepeatingRand(min, max, num) {
var arr = shuffle(range(min, max));
return arr.slice(0, num-1);
}
// Get 7 random numbers between and including 1 and 1000 that will *not* repeat
console.log(getNonRepeatingRand(1,1000,7));
A possibly slower, but less memory intensive method:
http://jsfiddle.net/Qnd8Q/
function rand(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function getNonRepeatingRand(min, max, num) {
var ret = [];
for (var i = 0; i < num; i++) {
var n = rand(min, max);
if (ret.indexOf(n) == -1) {
ret.push(n);
} else {
i--;
}
}
return ret;
}
console.log(getNonRepeatingRand(1,5,5));
var n = new Array(),num;
function TableOn()
{
document.write("<table border='1'>");
}
function TableOff()
{
document.write("</table>");
}
function check_repition()
{
num=Math.round((1+(Math.random()*40)))
if(n.indexOf(num)==-1)
return true;
else
return false;
}
function RandNum()
{
for(var i=0;i<7;i++)
{
if(check_repition())
n[i] =num;
else // keep checking
{
check_repition()
n[i] =num;
}
}
TableOn();
for(var c=0;c<7;c=c+1)
{
document.write("<tr><td>"+n[c]+"</td></tr>");
}
TableOff();
}
RandNum()