Page 1 of 1
can this function be made simpler
Posted: Sat Apr 15, 2006 9:12 am
by malcolmboston
Ive been using this same random checksum generator for as long as i can remember, it works perfectly but its more of an exercise on syntax and execution optimisation
Code: Select all
<?php
function checksumGenerator ($requiredLength = 32) { // declare a default value for the function
$alphabetArray = array(1 => "a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
"k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
"u", "v", "w", "x", "y", "z");
$letterArray = array(1 => 1, 2, 3, 4, 5, 6, 7, 8, 9, 0);
// auto-initialise the var
$checksum = '';
for ($i = 1; $i <= $requiredLength; $i++) {
if (rand(1, 2) === 1) {
// use alphabet
$randomItem = array_rand($alphabetArray, 1);
$checksum .= $alphabetArray[$randomItem];
} else {
// use letter
$randomItem = array_rand($letterArray, 1);
$checksum .= $letterArray[$randomItem];
}
}
return $checksum;
}
?>
can it be wrote any simpler (i dont want microtime())
also what sort of mathematics could i use to find out total possible combinations and collision likelihood, kudos to whoever can provide this
Thanks
Posted: Sat Apr 15, 2006 9:26 am
by printf
What's wrong with microtime(), it's a lot faster than doing silly loops!
Code: Select all
echo md5 ( uniqid ( microtime () ) );
printf!
Posted: Sat Apr 15, 2006 9:33 am
by timvw
The input size is 36 (26 chars and 10 numbers) items.
You choose 32 times one of those 36.
If you choose 1 times one of those 36 you have 36 possible results. (36 ^ 1 )
If you choose 2 times one of those 36 you have 36 * 36 possible results. (36 ^ 2)
If you choose 3 times one of those 36 you have 36 * 36 * 36 possible results. (36 ^ 3)
If you choose n times one of those 36 you have 36 ^ 32 possible results.
Re: can this function be made simpler
Posted: Sat Apr 15, 2006 9:34 am
by malcolmboston
malcolmboston wrote:i dont want microtime
the method u describe returns a a string with 32 characters, mine supports any number you choose, u could explode on the string to take it down to 16 for eg, but thats just messy in my opinion
besides this takes 0.002 for a 32 digit, u cannot really get much faster than that so in my opinion my way has more advantages over using your method
my $0.02
Posted: Sat Apr 15, 2006 9:35 am
by malcolmboston
timvw wrote:The input size is 36 (26 chars and 10 numbers) items.
You choose 32 times one of those 36.
If you choose 1 times one of those 36 you have 36 possible results. (36 ^ 1 )
If you choose 2 times one of those 36 you have 36 * 36 possible results. (36 ^ 2)
If you choose 3 times one of those 36 you have 36 * 36 * 36 possible results. (36 ^ 3)
If you choose n times one of those 36 you have 36 ^ 32 possible results.
any idea's on actual code to calculate that?
Re: can this function be made simpler
Posted: Sat Apr 15, 2006 9:44 am
by printf
malcolmboston wrote:malcolmboston wrote:i dont want microtime
the method u describe returns a a string with 32 characters, mine supports any number you choose, u could explode on the string to take it down to 16 for eg, but thats just messy in my opinion
besides this takes 0.002 for a 32 digit, u cannot really get much faster than that so in my opinion my way has more advantages over using your method
my $0.02
If you want 16, then just do..., also your idea will not ever be as random as my example, search google, you will find out why. The biggest flaw in your function is using array_rand(), it does not randomize in way that will return a unique index everytime!
Code: Select all
echo md5 ( uniqid ( microtime () ), true );
pif!
Posted: Sat Apr 15, 2006 9:44 am
by timvw
malcolmboston wrote:timvw wrote:The input size is 36 (26 chars and 10 numbers) items.
You choose 32 times one of those 36.
If you choose 1 times one of those 36 you have 36 possible results. (36 ^ 1 )
If you choose 2 times one of those 36 you have 36 * 36 possible results. (36 ^ 2)
If you choose 3 times one of those 36 you have 36 * 36 * 36 possible results. (36 ^ 3)
If you choose n times one of those 36 you have 36 ^ 32 possible results.
any idea's on actual code to calculate that?
http://www.php.net/pow.
Posted: Sat Apr 15, 2006 9:47 am
by feyd
The following may be more efficient (and more random)
Code: Select all
<?php
function checksumGenerator ($requiredLength = 32) { // declare a default value for the function
$a = ord('a');
// auto-initialise the var
$checksum = '';
for ($i = 1; $i <= $requiredLength; $i++) {
if (mt_rand(1, 2) % 2) {
// use alphabet
$checksum .= chr($a + mt_rand(0, 25));
} else {
// use number
$checksum .= strval(mt_rand(1, 10) % 10);
}
}
return $checksum;
}
?>
Code: Select all
[feyd@home]>php -r "$len = 32; $possible = '36'; $computed = 1; for($i = 0; $i < $len; $i++) $computed = bcmul($computed, $possible); echo $computed;"
63340286662973277706162286946811886609896461828096
Posted: Sat Apr 15, 2006 9:51 am
by printf
yes, feyd, that one is a lot nicer than the first one, and it will be nice and unique!
me likes...
pif!
Posted: Sat Apr 15, 2006 9:56 am
by malcolmboston
very nice indeed
whats this mean in your output feyd?
echo $computed;"
63340286662973277706162286946811886609896461828096
Posted: Sat Apr 15, 2006 10:00 am
by feyd
number of possible combinations when calling your function using the default 32 length. You can adjust the command I called PHP with to alter the length ($len) to any length to find out the number of permutations required for each length. Of course that's the maximum number of permutations required, likely the actual is less than half, possibly even the square root of it. Still quite large, but significantly less than the maximum.
Posted: Sat Apr 15, 2006 10:01 am
by malcolmboston
awesome thanks