Convert to C/C++?

Douglas Wells see at signature.invalid
Thu Jun 14 23:43:42 EDT 2007


In article <1181852202.897976.312280 at j4g2000prf.googlegroups.com>,  SpreadTooThin <bjobrien62 at gmail.com> writes:
> I am wondering if someone who knows the implemention of python's time
> could help converting this to c/c++....

First the obligatory sermon:

If you are truly intending to utilize a UUID generator on a UNIX
platform, I urge you to seek out and use a native implementation.
Both Linux and FreeBSD distributions include such a capability,
and there are also functions available in freely available libraries.
Such a native function would offer several advantages over the
code you are attempting to copy:

   1) it could utilize the full capability of the clock rather
      than be limited to the microseconds precision in gettimeofday;
   2) it is probably implemented utilizing a system locking function
      to provide a truly unique-per-system UID;
   3) it would almost certainly incorporate a per-machine unique
      identifier, as called for by the spec, and which is missing
      from your prototype code;
   4) it would have easier access to better pseudo-random number
      generators;
   4) it would probably be coded better than the code you provide,
      which squanders quite a bit of precision (I haven't counted
      exactly, but I would guess about 10 bits worth);
   
Also, it sounds as though you are not comfortable coding in C (as
most of the information that you seek is straight-forwardly available
from the Python and UNIX documentation), and there are numerous
subtleties in the code that you must develop:
   1) the management of endianness will require careful attention
      to your use of this function;
   2) conversion to and from 64-bit numbers requires attention to
      the suffixes.

With that said;

Python doesn't define the time epoch except on UNIX platforms, but
it's almost certainly the same as on UNIX.  So,

time.time() is equivalent to:
    double time_time (void) { struct timeval tv;
        gettimeofday (&tv, (void *) NULL);
        return tv.tv_sec + tv.tv_usec / 1e6); }

random.randrange(value) is approximately equivalent to:
    long random_randrange (unsigned long stop) {
	return rand () % stop; }
 - with the caveats that:
    1) you should choose a better pseudo-random number generator
       than rand();
    2) you should be sure to initialize the random function, e.g.,
       via srand();

>   nanoseconds = int(time.time() * 1e9)
>   # 0x01b21dd213814000 is the number of 100-ns intervals between the
>   # UUID epoch 1582-10-15 00:00:00 and the Unix epoch 1970-01-01 00:00:00.
>   self.timestamp = int(nanoseconds/100) + 0x01b21dd213814000L
>   self.clock_seq = random.randrange(1<<14L) # instead of stable storage
>   self.time_low = self.timestamp & 0xffffffffL
>   self.time_mid = (self.timestamp >> 32L) & 0xffffL
>   self.time_hi_version = (self.timestamp >> 48L) & 0x0fffL
>   self.clock_seq_low = self.clock_seq & 0xffL
>   self.clock_seq_hi_variant = (self.clock_seq >> 8L) & 0x3fL

You should look up the definition of the various fields (e.g.,
clock_seq, time_low, time_mid) in a UUID specification, for example
IETF RFC 4122.  They have precise width requirements.

>   #print 'timestamp ', self.timestamp, self.time_low, self.time_mid, self.time_hi_version
>   #print 'clock_seq ', self.clock_seq, self.clock_seq_low, self.clock_seq_hi_variant
> 
> vs unix gettimeofday....
> 
> int gettimeofday(struct timeval *tp, struct timezone *tzp);

By the way, the UNIX gettimeofday function does not include timezone:
the prototype of the second argument is "void *" and must be passed
as NULL.

Good luck, - dmw

-- 
.   Douglas Wells             .  Connection Technologies      .
.   Internet:  -sp9804- -at - contek.com-                     .



More information about the Python-list mailing list