2012-04-26 9 views
6

Utilizzando Perl, senza utilizzare alcun modulo aggiuntivo che non viene fornito con ActivePerl, come posso creare una stringa di 8 caratteri da 0-F. esempio 0F1672DA? Il padding dovrebbe essere controllabile e sono preferibili esattamente 8 caratteri.In Perl, come posso generare stringhe casuali composte da otto cifre esadecimali?

Più esempi dei tipi di stringhe che vorrei generare:

28DA9782 
55C7128A 
+5

Golf: 'perl -e'print [0..9, A..F ] -> [rand 16] per 1..8'' – daxim

+1

Perché downvoting? Ho bisogno di imparare la programmazione. Che cos'è lo stackoverflow se non questo tipo di domande? – unixman83

+4

Non ho votato il tuo post. Tuttavia, in generale, escludere qualsiasi modulo CPAN non è considerato favorevolmente. Inoltre, ci si aspetta che tu faccia uno sforzo per trovare una tua soluzione e chiedere aiuto con questo, piuttosto che aspettarti che gli altri ti diano soluzioni in scatola. –

risposta

15

In linea di principio, si dovrebbe essere in grado di fare

#!/usr/bin/env perl 

use strict; use warnings; 

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

Tuttavia, si può scoprire che — almeno su alcuni sistemi con alcuni perl s (se non tutti) — il range of rand is restricted to 32,768 values.

È anche possibile studiare il codice sorgente di String::Random per imparare come generare stringhe casuali che soddisfano altre condizioni.

Tuttavia, la mia cautela nei confronti dell'uso del rand integrato nel sistema Windows è ancora valida. Vedi Math::Random::MT per un RNG di alta qualità.

#!/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:

Ciò significa che la qualità dei numeri casuali di Perl varierebbe da una piattaforma all'altra, dai 15 bit di rand() in Windows a 48-bit su piattaforme POSIX come Linux con drand48().

Perl ora utilizza la propria implementazione interna drand48() su tutte le piattaforme. Questo non rende sicuro il perl's rand crittograficamente sicuro. [Perl # 115928]

+0

Sicuramente c'è un plugin che viene fornito con ActivePerl che supera il limite di 'rand'? – unixman83

+0

+1 per l'avviso 'rand' – unixman83

+1

Una soluzione potrebbe utilizzare' rand' per 1 cifra alla volta? Il tuo secondo esempio fa questo? – unixman83

4

Usa sprintf per convertire i numeri in esadecimale.

$foo .= sprintf("%x", rand 16) for 1..8; 
+0

+1 per semplicità – unixman83

7

esempio generale, consentendo ad ogni intervallo di caratteri:

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

alcune persone hanno menzionato il finestre termine di rand con il Max-Valore di rand (0x7FFF) o rand (32768) decimale, voglio superare questo con binario disinnesto operatore '< <'

# 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)) 
    ); 

Ma ritengo questo su come accademico, perché è un codice veramente imbarazzante che è difficile da capire.
Non lo userei nel codice della vita reale, solo se la velocità è il massimo.
Ma forse è la soluzione più veloce e sta dimostrando uno schema per superare la limitazione della funzione rand() sotto windows ...

+0

Questo non funzionerà secondo @Sinan. L'intervallo di 'rand' è solo di 32.768! – unixman83

+3

La mia affermazione era un po 'più debole: * Su almeno alcuni sistemi Windows, l'intervallo di 'rand' potrebbe essere limitato a 32.768 valori. –

+0

sì, ho letto il blog. –