On Jan 18, 2008 7:45 AM, bootleg86 bootleg86 <[EMAIL PROTECTED]> wrote:

> I can't for the life of me figure out what this is trying to do
> $token = $$ ^ unpack "%L*", `ps -A | "./bin/gzip"

Well, it's not complete, for one thing. What comes next?

> Just seems to be it's trying to generate some random number.
> I only know it's trying to XOR the process ID.

You've got the right idea. It looks as if somebody thought this was a
good way to choose a number that would be hard for anybody to predict,
even somebody who had the source code to the program.

> What does this part do?
> unpack "%L*", `ps -A | "./bin/gzip"

The part on the right looks to be the start of a shell command in
backticks. ps -A runs the ps command; the -A option means "Display
information about other users' processes including those without
controlling terminals," according to my manpage. It's hard to predict
what processes all users will be running at any given time.

Presumably the rest of the line feeds the ps data through gzip, a
compression program. The author of the program may be of the
impression that this will help make things unpredictable, but gzip
uses a pretty straightforward algorithm. In any case, the output of
gzip is presumably eventually passed back to perl as the return value
of the command in backticks. (Is there yet another process after
gzip?)

The unpack function, when given a "%" template, gives a checksum of
the data instead of the data itself.

Finally, as you saw, that checksum is xored with the current process
ID. Since the default checksum is 16 bits wide and (on most systems)
the pid is also 16 bits wide, the result is 16 hard-to-predict bits.
(For consistency, this line's author should have used an "S" format
instead of an "L" format in the unpack, although it could conceivably
have been an intentional decision to discard half of the available
bits.)

If that were my program, running under any modern perl version, I'd
exploit the fact that Perl's random number generator can give you 16
hard-to-predict bits much more easily. This line should be a drop-in
equivalent that's just as good, from an unpredictability standpoint,
and significantly faster and more portable:

    my $token = int rand 2**16;

Still, I wouldn't write it that way without seeing more about how
$token is used further down the code. It might be that you could (or
even should) use more bits than 16, if it's really important to make
your token unguessable. But you can't upgrade to 40 bits by simply
writing this:

    my $token = int rand 2**40;    # won't work

... because rand only produces a few bits of randomness each time it
is called. If you want a token with more bits, you can do something
like this:

    my $bits_of_randomness = 40;
    my $token = '';
    while (length($token) < ($bits_of_randomness/4)) {
        $token .= unpack "H4", pack "S", int rand 2**16;
    }

Of course, that may require changes to subsequent parts of the code
that expected $token to be an integer instead of a string, for
example.

Hope this helps!

--Tom Phoenix
Stonehenge Perl Training

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/


Reply via email to