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
Perl | rand() Function rand() function in Perl returns a random fractional number between 0 and the positive number value passed to it, or 1 if no value is specified. Automatically calls srand() to seed the random number generator unless it has already been called.
A random string is generated by first generating a stream of random numbers of ASCII values for 0-9, a-z and A-Z characters. All the generated integer values are then converted into their corresponding characters which are then appended to a StringBuffer.
Method 1: Using Math. random() Here the function getAlphaNumericString(n) generates a random number of length a string. This number is an index of a Character and this Character is appended in temporary local variable sb. In the end sb is returned.
Chars[Random(SequenceLength)]; end; Calling this function is just like this, for example : GenerateRandomString(6; 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'); And you will get a string like “M7DX9H”, with 6 characters consisting of caps letters and numbers (as our parameters).
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 perl
s (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]
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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With