Question

Using Perl, without using any extra modules that don't come with ActivePerl, how can I create a string of 8 characters from 0-F. example 0F1672DA? The padding should be controllable and exactly 8 characters is preferable.

More examples of the kinds of strings I would like to generate:

28DA9782
55C7128A
Was it helpful?

Solution

In principle, you ought to be able to do

#!/usr/bin/env perl

use strict; use warnings;

for (1 .. 10) {
    printf "%08X\n", rand(0xffffffff);
}

However, you may find out that —at least on some systems with some perls (if not all)— the range of rand is restricted to 32,768 values.

You can also study the source code of String::Random to learn how to generate random strings satisfying other conditions.

However, my caution against using the built in rand on Windows system still stands. See Math::Random::MT for a high quality RNG.

#!/usr/bin/env perl

use strict; use warnings;

my @set = ('0' ..'9', 'A' .. 'F');
my $str = join '' => map $set[rand @set], 1 .. 8;
print "$str\n";

PS: The issue with Perl's rand on Windows was fixed in 5.20:

This meant that the quality of perl's random numbers would vary from platform to platform, from the 15 bits of rand() on Windows to 48-bits on POSIX platforms such as Linux with drand48().

Perl now uses its own internal drand48() implementation on all platforms. This does not make perl's rand cryptographically secure. [perl #115928]

OTHER TIPS

General example, allowing any range of characters:

my @chars = ('0'..'9', 'A'..'F');
my $len = 8;
my $string;
while($len--){ $string .= $chars[rand @chars] };
print "$string\n";
sprintf("%08X", rand(0xFFFFFFFF))

some people mentioned the windows-limit of rand with the MAX-Value of rand(0x7FFF) or rand(32768) decimal, i would overcome this with binary shifting-operator '<<'

# overcomes the windows-rand()-only-works-with-max-15bit-(32767)-limitation:
#   needed 8*4==32bit random-number:
#     first get the 15 high-significant bits shift them 17bits to the left,
#     then the next 15bits shifted 2 bits to the left,
#     then the last 2 bits with no shifting:
printf( '%08X', (
    (rand(0x8000)<<17) + (rand(0x8000)<<2) + rand(0b100) )
      );

But i consider this only as academic, because it is really awkward code which is difficult to understand.
I would not use this in real-life code, only if speed mater the most.
But maybe its the fastest solution and it's demonstrating a schema to overcome the limitation of the rand()-function under windows...

Use sprintf to convert numbers to hex.

$foo .= sprintf("%x", rand 16) for 1..8;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top