2010-08-10 13 views
6

यह मेरी पहली पर्ल स्क्रिप्ट है। कभी:क्या पर्ल में यादृच्छिक फ़ाइल उत्पन्न करने का कोई और अधिक प्रभावी तरीका है?

#!/usr/bin/perl 

if ($#ARGV < 1) { die("usage: <size_in_bytes> <file_name>\n"); } 

open(FILE,">" . $ARGV[0]) or die "Can't open file for writing\n"; 

# you can control the range of characters here 
my $minimum = 32; 
my $range = 96; 

for ($i=0; $i< $ARGV[1]; $i++) { 
    print FILE chr(int(rand($range)) + $minimum); 
} 

close(FILE); 

इसका उद्देश्य generate a file in a specified size filled with random characters है।

यह काम करता है लेकिन यह बहुत धीमी है। 10 एमबी यादृच्छिक फ़ाइल लिखने में कुछ सेकंड लगते हैं।
क्या किसी के पास इसे तेजी से/बेहतर बनाने के सुझाव/सुझाव हैं? आम नौसिखिया गलतियों को इंगित करने के लिए भी स्वतंत्र महसूस करें।

उत्तर

6
  1. आप प्रत्येक बार जब आप इसे कॉल करते हैं तो आपके लिए एक से अधिक मूल्य बनाने के लिए rand पूछ सकते हैं।
  2. print पर कॉल करने से पहले कई वर्ण एकत्रित करें। एक समय में एक चरित्र को प्रिंट करना अक्षम है।

 

for (my $bytes = 0; $bytes < $num_bytes; $bytes += 4) { 
    my $rand = int(rand($range ** 4)); 
    my $string = ''; 
    for (1..4) { 
     $string .= chr($rand % $range + $minimum); 
     $rand = int($rand/$range); 
    } 
    print FILE $string; 
} 
+1

मुझे लगता है * perl स्ट्रीम में भेजे गए 4k हिस्सों में सबसे अच्छा काम करता है। धारा बफर आकार को बदलने के लिए संबंधित SO: http://stackoverflow.com/questions/1251062/how-can-i-set-the-file-read-buffer-size-in-perl-to-optimize-it-for -लर्ज-फाइल – Incognito

+0

आप 'my $ rand = int (रैंड ($ रेंज ** 4)) 'और' chr ($ rand% $ range + $ न्यूनतम) 'का उपयोग क्यों करते हैं, केवल' my $ rand = int (रैंड ($ रेंज) 'और' सीआर ($ रैंड + $ न्यूनतम) ' – Alexander

+0

'रैंड ($ रेंज ** 4)' में 4 यादृच्छिक वर्ण – mob

4

/dev/random से स्ट्रीम डेटा लिखें।

#!/usr/bin/perl 
use File::Copy; 
if ($#ARGV < 1) { die("usage: <size_in_bytes>\n"); } 
copy("/dev/random","tmp", $ARGV[0]) or die "Copy failed: $!"; 

कोड परीक्षण नहीं किया गया।

संपादित करें: चूंकि आप एक सीमा चाहते हैं, ऐसा करें।

आपकी सीमा 96 और 32 के बीच है, जो 64 की एक जगह है। 64 = 01000000b (हेक्स में 0x40)। बस अपनी संख्याएं उत्पन्न करें और थोड़ा सा preform करें और संख्या के विरुद्ध जो उत्पन्न होने के लिए मानों की सीमा है -1 और थोड़ा सा बाधा डालने से निचला बाध्य जोड़ें या इसके मूल्य (00100000b, या 0x20)

यह दे देगा आप चीजें करते हैं जैसे किसी भी यादृच्छिक स्ट्रिंग (केवल कच्चे हेक्स को/dev/random से पढ़ें) और डेटा को अपनी सीमा में बदलने के लिए करें।

+1

तुम्हारा मतलब/dev/यादृच्छिक, शायद। ध्यान दें कि यह केवल यूनिक्स जैसी प्रणाली है। –

+0

हां, इसे ढूंढने के लिए धन्यवाद। मैं शर्त लगा रहा हूं कि यह यूनिक्स पर कहां स्थित है, जहां पर स्थित है (usr/bin) – Incognito

+0

यह मुझे नियंत्रित करने की अनुमति नहीं देता कि कौन से पात्र लिखे गए हैं या नहीं। – quantumSoup

1

यदि आपको किसी श्रेणी से यादृच्छिक संख्या की आवश्यकता है, तो मुझे अधिक कुशल तरीके से अवगत नहीं है। आपकी स्क्रिप्ट मेरी पसंद करने के लिए समायोजित:

#!/usr/bin/perl 

use warnings; 
use strict; 

die("usage: $0 <size_in_bytes> <file_name>\n") unless @ARGV == 2; 

my ($num_bytes, $fname) = @ARGV; 

open(FILE, ">", $fname) or die "Can't open $fname for writing ($!)"; 

my $minimum = 32; 
my $range = 96; 

for (1 .. $num_bytes) { 
    print FILE pack("c", int(rand($range)) + $minimum); 
} 

close(FILE); 

मैं pack("c") का उपयोग जब मैं वास्तव में द्विआधारी की जरूरत है। chr() ठीक हो सकता है भी लेकिन BTW IIRC यह वास्तव में क्या चरित्र अपने वातावरण एन्कोडिंग उपयोग कर रहा है पर निर्भर करता है (लगता है ASCII बनाम UTF8।)

यदि आप वास्तव में Windows संगतता के लिए बाइनरी फ़ाइल की जरूरत है आप के बाद openbinmode FILE; जोड़ सकते हैं ।

अन्यथा, यदि सीमा वैकल्पिक है, तो आप बस dd if=/dev/random of=$filename bs=1 count=$size_of_the_output (या लिनक्स पर तेजी से क्रिप्टो-असुरक्षित /dev/urandom) कर सकते हैं। लेकिन यह बहुत धीमा होगा क्योंकि /dev/random वास्तव में असली यादृच्छिक बिट्स देने की कोशिश करता है - जैसे ही वे उपलब्ध हो जाते हैं। और यदि उनमें पर्याप्त नहीं है (उदा। आपके प्लेटफ़ॉर्म में एच/डब्ल्यू आरएनजी नहीं है) तो प्रदर्शन वास्तव में भुगतना होगा - तेजस्वी libc के छद्म-यादृच्छिक संख्या जेनरेटर की तुलना में (पर्ल rand() को लागू करने के लिए आंतरिक रूप से उपयोग करता है)।

संबंधित मुद्दे

 संबंधित मुद्दे