Textual input to seeded random - javascript

How would I take a textual input from the user (anything their keyboard would allow them to type), and transfer it to a number?
From there, I would probably take that number, and feed it into a seeded random number generator.
I'm getting the idea from Minecraft's random seed option, but I can't find anything on it.

There are probably more interesting algorithms but this just converts the characters to ints and multiplies it by the position in order to weight them (so that 'abc' is different than 'cba'). You could also use a hash function of some kind as well, but I thought that might be overkill for this purpose.
​
var input = 'askljfhasjfh', num = 0;
for (var i = 0, len = input.length; i < len; ++i) {
num += input.charCodeAt(i) * (i + 1);
}
console.log(num);
Keep in mind though, you can't seed the Math.random() function in Javascript, it always just uses the current date for the seed.

Related

Converting an arbitrary seed into a float between 0 and 1

I want to be able to change any string containing any utf-8 into a random number between 0 and 1.
I can convert any seed that is a number with the following:
Math.abs(Math.sin(seed));
From this I'm able to generate a pseudo seeded Math.random()-like number.
So it's converting a string into a number. I looked into using crypto and found that making a digest of the string works but is incredibly slow, and is a bit overkill.
Any ideas on how to accomplish this?
Using String.prototype.charCodeAt() you can generate an integer representation:
function stringToSeed(str){
var values = [];
for (var i = 0, len = str.length; i < len; i++) {
values.push(str.charCodeAt(i));
}
// concatenatte and coerce to integer
return values.join('') + 0;
}
var seed = stringToSeed(string);
You can then pass this seed to sin as you were before.
The thought behind concatenation instead of simply adding the values is to ensure that order is taken into account for randomness, otherwise "AB" and "BA" would produce the same value, for example.

Random number in JavaScript per day once

I'm in the process of coding an application that does the following:
Generates a random number with 4 digits.
Changes it once per calendar day.
Won't change that full day. Only once in a day.
I tried:
function my_doubt()
{
var place = document.getElementById("my_div")
place.innerHTML=Math.floor((Math.random()*100)+1);
}
I'm getting a random number with Math.random(). However, I'm rather clueless about how to generate a different number for each day. What are some common approaches for tackling this problem?
Note: It doesn't have to be really random. A pseudo - random number is also OK.
You need to seed the random number generator with a number derived from the current date, for example "20130927" for today.
You haven't been clear about your requirements, so I don't know how random you need (do you have requirements for how uniform of a distribution you need?).
This will generate a random looking 4 digit number which may be good enough for your requirements, but if you perform an analysis you'll find the number isn't actually very random:
function rand_from_seed(x, iterations){
iterations = iterations || 100;
for(var i = 0; i < iterations; i++)
x = (x ^ (x << 1) ^ (x >> 1)) % 10000;
return x;
}
var random = rand_from_seed(~~((new Date)/86400000)); // Seed with the epoch day.
Now that your question is a bit more reasonable, clear and nicer in tone. I can give you a way to get the same result on the client-side. However as others mentioned, to maintain consistency, you probably want to maintain the number on the server to ensure consistency.
var oneDayInMs = 1000*60*60*24;
var currentTimeInMs = new Date().getTime(); // UTC time
var timeInDays = Math.floor(currentTimeInMs / oneDayInMs);
var numberForToday = timeInDays % 9999;
console.log(numberForToday);
// zero-filling of numbers less than four digits might be optional for you
// zero-filled value will be a string to maintain its leading 0s
var fourDigitNumber = numberForToday.toString();
while(fourDigitNumber.length < 4)
{
fourDigitNumber = 0+fourDigitNumber;
}
console.log(fourDigitNumber);
// remember that this number rotates every and is unique for 10000 days
1)create a random number in javascript
2)store in cookie that will expire after one day
3)get value from cookie, if it does not exist goto 1

creating a simple one-way hash

Are there any standard hash functions/methods that maps an arbitrary 9 digit integer into another (unique) 9 digit integer, such that it is somewhat difficult to map back (without using brute force).
Hashes should not collide, so every output 1 ≤ y < 10^9 needs to be mapped from one and only one input value in 1 ≤ x < 10^9.
The problem you describe is really what Format-Preserving Encryption aims to solve.
One standard is currently being worked out by NIST: the new FFX mode of encryption for block ciphers.
It may be more complex than what you expected though. I cannot find any implementation in Javascript, but some examples exist in other languages: here (Python) or here (C++).
You are requiring a non-colliding hash function with only about 30 bits. That's going to be a tall order for any hash function. Actually, what you need is not a Pseudo Random Function such as a hash but a Pseudo Random Permutation.
You could use an encryption function for this, but you would obviously need to keep the key secret. Furthermore, encryption functions normally bits as input and output, and 10^9 is not likely to use an exact number of bits. So if you are going for such an option you may have to use format preserving encryption.
You may also use any other function that is a PRP within the group 0..10^9-1 (after decrementing the value with 1), but if an attacker finds out what parameters you are using then it becomes really simple to revert back to the original. An example would be a multiplication with a number that is relatively prime with 10^9-1, modulo 10^9-1.
This is what i can come up with:
var used = {};
var hash = function (num) {
num = md5(num);
if (used[num] !== undefined) {
return used[num];
} else {
var newNum;
do {
newNum = Math.floor(Math.random() * 1000000000) + 1;
} while (contains(newNum))
used[num] = newNum;
return newNum;
}
};
var contains = function (num) {
for (var i in used) {
if (used[i] === num) {
return true;
}
}
return false;
};
var md5 = function (num) {
//method that return an md5 (or any other) hash
};
I should note however that it will run into problems when you try to hash a lot of different numbers because the do..while will produce random numbers and compare them with already generated numbers. If you have already generated a lot of numbers it will get more and more unlikely to find the remaining ones.

Creating a random number generator in jscript and prevent duplicates

We are trying to create a random number generator to create serial numbers for products on a virtual assembly line.
We got the random numbers to generate, however since they are serial numbers we don't want it to create duplicates.
Is there a way that it can go back and check to see if the number generated has already been generated, and then to tell it that if it is a duplicate to generate a new number, and to repeat this process until it has a "unique" number.
The point of a serial number is that they're NOT random. Serial, by definition, means that something is arranged in a series. Why not just use an incrementing number?
The easiest way to fix this problem is to avoid it. Use something that is monotonically increasing (like time) to form part of your serial number. To that you can prepend some fixed value that identifies the line or something.
So your serial number format could be NNNNYYYYMMDDHHMMSS, where NNNN is a 4-digit line number and YYYY is the 4 digit year, MM is a 2 digit month, ...
If you can produce multiple things per second per line, then add date components until you get to the point where only one per unit time is possible -- or simply add the count of items produced this day to the YYYYMMDD component (e.g., NNNNYYYYMMDDCCCCCC).
With a truly random number you would have to store the entire collection and review it for each number. Obviously this would mean that your generation would become slower and slower the larger the number of keys you generate (since it would have to retry more and more often and compare to a larger dataset).
This is entirely why truly random numbers just are never used for this purpose. For serial numbers the standard is always to just do a sequential number - is there any real real for them to be random?
Unique IDs are NEVER random - GUIDs and the like are based on the system time and (most often) MAC address. They're globally unique because of the algorithm used and the machine specifics - not because of the size of the value or any level of randomness.
Personally I would do everything I could to either use a sequential value (perhaps with a unique prefix if you have multiple channels) or, better, use a real GUID for your purpose.
is this what you are looking for?
var rArray;
function fillArray (range)
{
rArray = new Array ();
for(var x = 0; x < range; x++)
rArray [x] = x;
}
function randomND (range)
{
if (rArray == null || rArray.length < 1)
fillArray (range);
var pos = Math.floor(Math.random()*rArray.length);
var ran = rArray [pos];
for(var x = pos; x < rArray.length; x++)
rArray [x] = rArray [x+1];
var tempArray = new Array (rArray.length-1)
for(var x = 0; x < tempArray.length; x++)
tempArray [x] = rArray [x];
rArray = tempArray;
return ran;
}

How is randomness achieved with Math.random in javascript?

How is randomness achieved with Math.random in javascript? I've made something that picks between around 50 different options randomly. I'm wondering how comfortable I should be with using Math.random to get my randomness.
From the specifications:
random():
Returns a Number value with positive
sign, greater than or equal to 0 but
less than 1, chosen randomly or pseudo
randomly with approximately uniform
distribution over that range, using an
implementation-dependent algorithm or
strategy. This function takes no
arguments.
So the answer is that it depends on what JavaScript engine you're using.
I'm not sure if all browsers use the same strategy or what that strategy is unfortunately
It should be fine for your purposes. Only if you're doing a large amount of numbers would you begin to see a pattern
Using Math.random() is fine if you're not centrally pooling & using the results, i.e. for OAuth.
For example, our site used Math.random() to generate random "nonce" strings for use with OAuth. The original JavaScript library did this by choosing a character from a predetermined list using Math.random(): i.e.
for (var i = 0; i < length; ++i) {
var rnum = Math.floor(Math.random() * chars.length);
result += chars.substring(rnum, rnum+1);
}
The problem is, users were getting duplicate nonce strings (even using a 10 character length - theoretically ~10^18 combinations), usually within a few seconds of each other. My guess this is due to Math.random() seeding from the timestamp, as one of the other posters mentioned.
The exact implementation can of course differ somewhat depending on the browser, but they all use some kind of pseudo random number generator. Although it's not really random, it's certainly good enough for all general purposes.
You should only be worried about the randomness if you are using it for something that needs exceptionally good randomness, like encryption or simulating a game of chance in play for money, but then you would hardly use Javascript anyway.
It's 100% random enough for your purposes. It's seeded by time, so every time you run it, you'll get different results.
Paste this into your browsers address bar...
javascript:alert(Math.random() * 2 > 1);
and press [Enter] a few times... I got "true, false, false, true" - random enough :)
This is a little overkill...but, I couldn't resist doing this :)
You can execute this in your browser address bar. It generates a random number between 0 and 4, 100000 times. And outputs the number of times each number was generated and the number of times one random number followed the other.
I executed this in Firefox 3.5.2. All the numbers seem to be about equal - indicating no bias, and no obvious pattern in the way the numbers are generated.
javascript:
var max = 5;
var transitions = new Array(max);
var frequency = new Array(max);
for (var i = 0; i < max; i++)
{
transitions[i] = new Array(max);
}
var old = 0, curr = 0;
for (var i = 0; i < 100000; i++)
{
curr = Math.floor(Math.random()*max);
if (frequency[curr] === undefined)
{
frequency[curr] = -1;
}
frequency[curr] += 1;
if (transitions[old][curr] === undefined)
{
transitions[old][curr] = -1;
}
transitions[old][curr] += 1;
old = curr;
}
alert(frequency);
alert(transitions);

Categories