can this function be made simpler

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
malcolmboston
DevNet Resident
Posts: 1826
Joined: Tue Nov 18, 2003 1:09 pm
Location: Middlesbrough, UK

can this function be made simpler

Post 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
printf
Forum Contributor
Posts: 173
Joined: Wed Jan 12, 2005 5:24 pm

Post by printf »

What's wrong with microtime(), it's a lot faster than doing silly loops!

Code: Select all

echo md5 ( uniqid ( microtime () ) );
printf!
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post 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.
malcolmboston
DevNet Resident
Posts: 1826
Joined: Tue Nov 18, 2003 1:09 pm
Location: Middlesbrough, UK

Re: can this function be made simpler

Post 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
malcolmboston
DevNet Resident
Posts: 1826
Joined: Tue Nov 18, 2003 1:09 pm
Location: Middlesbrough, UK

Post 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?
printf
Forum Contributor
Posts: 173
Joined: Wed Jan 12, 2005 5:24 pm

Re: can this function be made simpler

Post 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!
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post 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.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post 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
printf
Forum Contributor
Posts: 173
Joined: Wed Jan 12, 2005 5:24 pm

Post by printf »

yes, feyd, that one is a lot nicer than the first one, and it will be nice and unique!

me likes...

pif!
malcolmboston
DevNet Resident
Posts: 1826
Joined: Tue Nov 18, 2003 1:09 pm
Location: Middlesbrough, UK

Post by malcolmboston »

very nice indeed

whats this mean in your output feyd?

echo $computed;"
63340286662973277706162286946811886609896461828096
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post 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.
malcolmboston
DevNet Resident
Posts: 1826
Joined: Tue Nov 18, 2003 1:09 pm
Location: Middlesbrough, UK

Post by malcolmboston »

awesome thanks
Post Reply