Get tick count

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Get tick count

Post by alex.barylski »

I could have swore I have seen a function like this in PHP in the past...but maybe I'm remember wrong...I have no idea...

Anyways, I'm trying to generate a unique MD5 hash by:

Code: Select all

$new_sid = md5(time()); // Generate SID using current timestamp
Problem is...it's possible 2 processes or threads call this code at the exact same time in terms of seconds...so what I wanted was to use clock cycles as I believe it is gauranteed to be unique then on single CPU machines - which is another problem I need to address, as I imagine many servers in the near future (if not already) will incorporate multi-processor's

So I ask...2 questions actually:

1) Is there not a tick_* type function which returns the number of clock cycles - using native PHP code which is availble on many machines? No extensions please...

2) As opposed to randomly selecting a single character 32 times - can anyone think of a fairly failsafe way of generating a unique ID???

Cheers :)
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post by alex.barylski »

I don't think either are as unique or accurate as a CPU tick count

I think the potential for overlap using either is likely as it is using just time() as microtime() just returns time in milliseconds...

I have to go either tick count or random character generation...

I'm thinking random character generation would be best...
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

What's wrong with http://www.php.net/uniqid ?
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post by alex.barylski »

I never said anything was wrong with it...

It's just not ideal...it's the exact same thing AKAPJ suggested as it uses microtime...

p.s-I had no knowledge of that function prior to your post - thanks :P

Cheers :)
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Post by Benjamin »

Code: Select all

function GenerateRandomString($minlength, $maxlength, $uselower, $useupper, $usespecial, $usenumbers) {
  $charset = null;
  $key = null;
  if ($uselower)   $charset .= "abcdefghijklmnopqrstuvwxyz";
  if ($useupper)   $charset .= "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  if ($usespecial) $charset .= "~@#$%^*()_+-={}|][";   // Note: using all special characters this reads: "~!@#$%^&*()_+`-={}|\\]?[\":;'><,./";
  if ($usenumbers) $charset .= "0123456789";
  if ($minlength > $maxlength) $length = mt_rand ($maxlength, $minlength);
  else                         $length = mt_rand ($minlength, $maxlength);
  for ($i=0; $i<$length; $i++) $key .= $charset[(mt_rand(0,(strlen($charset)-1)))];
  return $key;
}
User avatar
Oren
DevNet Resident
Posts: 1640
Joined: Fri Apr 07, 2006 5:13 am
Location: Israel

Post by Oren »

Maybe you want something like this?

Code: Select all

$token = md5(uniqid(rand(), true));
Edit: I've just realized you can find this example on php.net too, I took it from http://phpsec.org anyway :wink:
User avatar
AKA Panama Jack
Forum Regular
Posts: 878
Joined: Mon Nov 14, 2005 4:21 pm

Post by AKA Panama Jack »

Hockey wrote:I don't think either are as unique or accurate as a CPU tick count

I think the potential for overlap using either is likely as it is using just time() as microtime() just returns time in milliseconds...

I have to go either tick count or random character generation...

I'm thinking random character generation would be best...
The likelyhood that two people access the site at the same time will get the exact same microtime result is millions to one. We are talking one millionth of a second increments here.
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Post by Benjamin »

Considering the fact that it takes CPU ticks to update microtime, and Linux is a multi process operating system, and the same process can't do two things at once, it would be impossible for 2 people to get the same microtime.
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Post by RobertGonzalez »

What if you concatenated the user's IP address to the time before hashing it? What are the chances that two or more users would be using the same IP and generate the ID at the exact same time? Just thought I'd throw it out there. I didn't put a whole lot of thought into it so it could be a way-off type of suggestion. :)
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post by alex.barylski »

AKA Panama Jack wrote:
Hockey wrote:I don't think either are as unique or accurate as a CPU tick count

I think the potential for overlap using either is likely as it is using just time() as microtime() just returns time in milliseconds...

I have to go either tick count or random character generation...

I'm thinking random character generation would be best...
The likelyhood that two people access the site at the same time will get the exact same microtime result is millions to one. We are talking one millionth of a second increments here.
First off...it just dawned on me...that microtime returned time in micro seconds NOT milli seconds...which was the reason I expressed dought in the first place... :oops:


But...I'll explain my reasoning...perhaps incorrect...but I'll explain anyways so everyone understands where I'm coming from and doesn't think I'm just an idiot... :P

It's been a long time since I've done any assembler or read anything of that nature...so don't quote me on anything...but...

A 950Mhz processor like my AMD950 clocks at 950 million cycles/second

Every statement in PHP is converted into a high level byte code which is then passed to an interpreter, which then basically executes the machine specific instruction(s) to carry out that task. Every machines instruction set is different from the next...some machines have instructions which only expend a few cycles and other instructions consume more than a dozen.

For instance consider the x86 familiy of processors and the very popular MOV instruction.

286/386 used 2 clock cycles whereas the 486 used only one.

Basically what this says to me is: 950 million cycles/second equals 950 million MOV instructions in one second on a 486 or 475 million on 286/386...

Now lets assume for the sake of arguing that:

Code: Select all

$token = md5(uniqid());
Results in approximately 300 instructions, each of which consumes 10 cycles...

on my AMD950 that is only 3000 cycles which leaves: 949997000 cycles unused in one second, so in one second my AMD950 could execute the above code snippet:

316666.66666666666666666666666667 times in one second!!!

This calculation assumes were using only the raw resources of the CPU and there is no OS or PHP scripts/interpreters, and other processes, etc...

What this says to me, is that under an ideal situation, where our required instructions for the above PHP code snippet results in 300 instructions at 10 clock cycles each...what this means IMHO...is that:

Code: Select all

$token = md5(uniqid());
Could execute 316666 times in one second that's alot of times to execute code in one second...

The point is...if this is true...mktime, time, microtime, etc...all return the "time" at current execution but the above calculation tells me that microtime could be called 316666 times in one second...that means...

Let me think here...i'm starting to loose myself :P

Thus the reason I wanted a cycle count as opposed to microtime...cycle counts, like that returned by Intels Read Time Stamp Counter return the number of cycles expended since bootup...

This *is* guaranteed to be unique everytime you check it...as calling the RDTSC instruction needs to be invoked at a minimum and thus uses clock cycles...

So yea...it should always be unique :P

Now, again, this assumes an ideal working environment...no OS doing any fancy task switching, etc...but consider this...

Although I was incorrect in thinking microtime was returning milliseconds not microseconds... :P even microseconds, on machines which are capable of performing in the nanoseconds and even faster with time to come...I was just trying to give my code a consistent gauantee of uniqueness...at least on single processor machines anyways :)

It's obvious to me now...I will likely just stick with randomized characters and hope for the best :)

Cheers :)
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post by alex.barylski »

agtlewis wrote:Considering the fact that it takes CPU ticks to update microtime, and Linux is a multi process operating system, and the same process can't do two things at once, it would be impossible for 2 people to get the same microtime.
Actually...it's not impossible... 8)

The faster computers get...the more likley it is going to occur...Servers are usually a helluva lot faster than my desktop...like 3Ghz is probably not uncommon...also considering the fact that some CPU's are capable of basically executing more than one instruction at once...my worries were not %100 pointless...

There are a ton of variables at play in estimating butting of heads between two consecutive calls to microtime() but I'm almost %110 positive it's very possible...

I wanted a clock cycle count because that would scale with the speed of a CPU unlike microtime which is fixed at one millionth of a second.

Cheers :)
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post by alex.barylski »

Everah wrote:What if you concatenated the user's IP address to the time before hashing it? What are the chances that two or more users would be using the same IP and generate the ID at the exact same time? Just thought I'd throw it out there. I didn't put a whole lot of thought into it so it could be a way-off type of suggestion. :)
Anything to further add entropy to the final result I guess would help... :P

I was after a one size fit all solution, but for now I guess I'll just go the typical direction and randomize my data the best I can :)

Cheers :)
Post Reply