Small Bias
##Small Bias
FirstFirst a nit pick, Math.random()
generates a number from 0 to < 1. It will never generate 1. Thus to get a statistical odds of 1/2 you must test either Math.random() < 0.5
or Math.random() >= 0.5
. Testing Math.random() > 0.5 ? char : char.toUpperCase()
will give a very (VERY) small bias in favor of upper case characters.
##Dramatic Bias
Dramatic Bias
##Performance
Performance
##Small Bias
First a nit pick, Math.random()
generates a number from 0 to < 1. It will never generate 1. Thus to get a statistical odds of 1/2 you must test either Math.random() < 0.5
or Math.random() >= 0.5
. Testing Math.random() > 0.5 ? char : char.toUpperCase()
will give a very (VERY) small bias in favor of upper case characters.
##Dramatic Bias
##Performance
Small Bias
First a nit pick, Math.random()
generates a number from 0 to < 1. It will never generate 1. Thus to get a statistical odds of 1/2 you must test either Math.random() < 0.5
or Math.random() >= 0.5
. Testing Math.random() > 0.5 ? char : char.toUpperCase()
will give a very (VERY) small bias in favor of upper case characters.
Dramatic Bias
Performance
##Bias##Small Bias
First a nit pick, Math.random()
generates a number from 0 to < 1. It will never generate 1. Thus to get a statistical odds of 1/2 you must test either Math.random() < 0.5
or Math.random() >= 0.5
. Testing Math.random() > 0.5 ? char : char.toUpperCase()
will give a very (VERY) small bias in favor of upper case characters.
##Update##Dramatic Bias
Also there is a very strong bias towards numerals in your function with a 0-9 being 2 times more likely than a-z or A-Z
canvas.width = innerWidth - 10;
const ctx = canvas.getContext("2d");
const w = canvas.width;
const h = canvas.height;
const chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
var testCount = 2;
const val = new Array(chars.length)
val.fill(0);
const func = randString;
function randString() {
return [
...Math.random()
.toString(36)
.substr(2, 5),
].map(element => (Math.random() > 0.5 ? element : element.toUpperCase())).join('');
}
function testRandomness() {
var i = testCount;
while (i--) {
const a = func();
for (const c of a) { val[chars.indexOf(c)] += 1 }
}
const max = Math.max(...val);
const w = canvas.width;
const h = canvas.height;
ctx.clearRect(0, 0, w, h);
const ww = w / val.length;
i = val.length;
ctx.fillStyle = "blue";
while (i--) {
if(chars[i] === "z") { ctx.fillStyle = "green" }
if(chars[i] === "9") { ctx.fillStyle = "red" }
const v = val[i] / max * h;
ctx.fillRect(i * ww, h - v, ww- 2, v)
}
setTimeout(testRandomness, 1000 / 30);
}
testRandomness();
canvas.addEventListener("click",()=> (testCount = 10000,d.textContent = "Sample rate ~300,000per sec") ,{once:true});
body { font-family: arial black; }
canvas {
padding: 0px;
}
#a { color:red; }
#b { color:green; }
#c { color:blue; }
#d { font-family: arial; }
<canvas id="canvas"></canvas>
<span id="a">Red</span> 0-9 <span id="b">Green</span> a-z <span id="c">Blue</span> A-Z <span id="d">Click graph to increase sample rate to 10000</span>
Click the graph to increase the tests per sample to 10000 per 30th second (approx) and you will see that apart from the numeral bias the graph quickly becomes very flat showing no other major bias (the uppercase bias is way to small to see)
The reason for the bias is that you split the characters a-z in two when you convert half to uppercase.
##Bias
First a nit pick, Math.random()
generates a number from 0 to < 1. It will never generate 1. Thus to get a statistical odds of 1/2 you must test either Math.random() < 0.5
or Math.random() >= 0.5
. Testing Math.random() > 0.5 ? char : char.toUpperCase()
will give a very (VERY) small bias in favor of upper case characters.
##Update Bias
Also there is a very strong bias towards numerals in your function with a 0-9 being 2 times more likely than a-Z
canvas.width = innerWidth - 10;
const ctx = canvas.getContext("2d");
const chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
var testCount = 2;
const val = new Array(chars.length)
val.fill(0);
const func = randString;
function randString() {
return [
...Math.random()
.toString(36)
.substr(2, 5),
].map(element => (Math.random() > 0.5 ? element : element.toUpperCase())).join('');
}
function testRandomness() {
var i = testCount;
while (i--) {
const a = func();
for (const c of a) { val[chars.indexOf(c)] += 1 }
}
const max = Math.max(...val);
const w = canvas.width;
const h = canvas.height;
ctx.clearRect(0, 0, w, h);
const ww = w / val.length;
i = val.length;
ctx.fillStyle = "blue";
while (i--) {
if(chars[i] === "z") { ctx.fillStyle = "green" }
if(chars[i] === "9") { ctx.fillStyle = "red" }
const v = val[i] / max * h;
ctx.fillRect(i * ww, h - v, ww- 2, v)
}
setTimeout(testRandomness, 1000 / 30);
}
testRandomness();
canvas.addEventListener("click",()=> (testCount = 10000,d.textContent = "Sample rate ~300,000per sec") ,{once:true});
body { font-family: arial black; }
canvas {
padding: 0px;
}
#a { color:red; }
#b { color:green; }
#c { color:blue; }
#d { font-family: arial; }
<canvas id="canvas"></canvas>
<span id="a">Red</span> 0-9 <span id="b">Green</span> a-z <span id="c">Blue</span> A-Z <span id="d">Click graph to increase sample rate to 10000</span>
Click the graph to increase the tests per sample to 10000 per 30th second (approx) and you will see that apart from the numeral bias the graph quickly becomes very flat showing no other major bias (the uppercase bias is way to small to see)
##Small Bias
First a nit pick, Math.random()
generates a number from 0 to < 1. It will never generate 1. Thus to get a statistical odds of 1/2 you must test either Math.random() < 0.5
or Math.random() >= 0.5
. Testing Math.random() > 0.5 ? char : char.toUpperCase()
will give a very (VERY) small bias in favor of upper case characters.
##Dramatic Bias
Also there is a very strong bias towards numerals in your function with a 0-9 being 2 times more likely than a-z or A-Z
canvas.width = innerWidth - 10;
const ctx = canvas.getContext("2d");
const w = canvas.width;
const h = canvas.height;
const chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
var testCount = 2;
const val = new Array(chars.length)
val.fill(0);
const func = randString;
function randString() {
return [
...Math.random()
.toString(36)
.substr(2, 5),
].map(element => (Math.random() > 0.5 ? element : element.toUpperCase())).join('');
}
function testRandomness() {
var i = testCount;
while (i--) {
const a = func();
for (const c of a) { val[chars.indexOf(c)] += 1 }
}
const max = Math.max(...val);
ctx.clearRect(0, 0, w, h);
const ww = w / val.length;
i = val.length;
ctx.fillStyle = "blue";
while (i--) {
if(chars[i] === "z") { ctx.fillStyle = "green" }
if(chars[i] === "9") { ctx.fillStyle = "red" }
const v = val[i] / max * h;
ctx.fillRect(i * ww, h - v, ww- 2, v)
}
setTimeout(testRandomness, 1000 / 30);
}
testRandomness();
canvas.addEventListener("click",()=> (testCount = 10000,d.textContent = "Sample rate ~300,000per sec") ,{once:true});
body { font-family: arial black; }
canvas {
padding: 0px;
}
#a { color:red; }
#b { color:green; }
#c { color:blue; }
#d { font-family: arial; }
<canvas id="canvas"></canvas>
<span id="a">Red</span> 0-9 <span id="b">Green</span> a-z <span id="c">Blue</span> A-Z <span id="d">Click graph to increase sample rate to 10000</span>
Click the graph to increase the tests per sample to 10000 per 30th second (approx) and you will see that apart from the numeral bias the graph quickly becomes very flat showing no other major bias (the uppercase bias is way to small to see)
The reason for the bias is that you split the characters a-z in two when you convert half to uppercase.
##Update Bias
Also there is a very strong bias towards numerals in your function with a 0-9 being 2 times more likely than a-Z
The following snippet counts the occurrence of each character generated by your function and plots them (normalized) on a graph.
I animated it slowly for dramatic effect.
canvas.width = innerWidth - 10;
const ctx = canvas.getContext("2d");
const chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
var testCount = 2;
const val = new Array(chars.length)
val.fill(0);
const func = randString;
function randString() {
return [
...Math.random()
.toString(36)
.substr(2, 5),
].map(element => (Math.random() > 0.5 ? element : element.toUpperCase())).join('');
}
function testRandomness() {
var i = testCount;
while (i--) {
const a = func();
for (const c of a) { val[chars.indexOf(c)] += 1 }
}
const max = Math.max(...val);
const w = canvas.width;
const h = canvas.height;
ctx.clearRect(0, 0, w, h);
const ww = w / val.length;
i = val.length;
ctx.fillStyle = "blue";
while (i--) {
if(chars[i] === "z") { ctx.fillStyle = "green" }
if(chars[i] === "9") { ctx.fillStyle = "red" }
const v = val[i] / max * h;
ctx.fillRect(i * ww, h - v, ww- 2, v)
}
setTimeout(testRandomness, 1000 / 30);
}
testRandomness();
canvas.addEventListener("click",()=> (testCount = 10000,d.textContent = "Sample rate ~300,000per sec") ,{once:true});
body { font-family: arial black; }
canvas {
padding: 0px;
}
#a { color:red; }
#b { color:green; }
#c { color:blue; }
#d { font-family: arial; }
<canvas id="canvas"></canvas>
<span id="a">Red</span> 0-9 <span id="b">Green</span> a-z <span id="c">Blue</span> A-Z <span id="d">Click graph to increase sample rate to 10000</span>
Click the graph to increase the tests per sample to 10000 per 30th second (approx) and you will see that apart from the numeral bias the graph quickly becomes very flat showing no other major bias (the uppercase bias is way to small to see)
Also note as pointed out in the other answer, there is a small chance that the returned string is less than 5 characters long.
##Performance
##Performance
##Update Bias
Also there is a very strong bias towards numerals in your function with a 0-9 being 2 times more likely than a-Z
The following snippet counts the occurrence of each character generated by your function and plots them (normalized) on a graph.
I animated it slowly for dramatic effect.
canvas.width = innerWidth - 10;
const ctx = canvas.getContext("2d");
const chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
var testCount = 2;
const val = new Array(chars.length)
val.fill(0);
const func = randString;
function randString() {
return [
...Math.random()
.toString(36)
.substr(2, 5),
].map(element => (Math.random() > 0.5 ? element : element.toUpperCase())).join('');
}
function testRandomness() {
var i = testCount;
while (i--) {
const a = func();
for (const c of a) { val[chars.indexOf(c)] += 1 }
}
const max = Math.max(...val);
const w = canvas.width;
const h = canvas.height;
ctx.clearRect(0, 0, w, h);
const ww = w / val.length;
i = val.length;
ctx.fillStyle = "blue";
while (i--) {
if(chars[i] === "z") { ctx.fillStyle = "green" }
if(chars[i] === "9") { ctx.fillStyle = "red" }
const v = val[i] / max * h;
ctx.fillRect(i * ww, h - v, ww- 2, v)
}
setTimeout(testRandomness, 1000 / 30);
}
testRandomness();
canvas.addEventListener("click",()=> (testCount = 10000,d.textContent = "Sample rate ~300,000per sec") ,{once:true});
body { font-family: arial black; }
canvas {
padding: 0px;
}
#a { color:red; }
#b { color:green; }
#c { color:blue; }
#d { font-family: arial; }
<canvas id="canvas"></canvas>
<span id="a">Red</span> 0-9 <span id="b">Green</span> a-z <span id="c">Blue</span> A-Z <span id="d">Click graph to increase sample rate to 10000</span>
Click the graph to increase the tests per sample to 10000 per 30th second (approx) and you will see that apart from the numeral bias the graph quickly becomes very flat showing no other major bias (the uppercase bias is way to small to see)
Also note as pointed out in the other answer, there is a small chance that the returned string is less than 5 characters long.
##Performance