Dd से / dev / random अलग फ़ाइल आकार क्यों देते हैं?


26

मैं एक ubuntu प्रणाली पर निम्नलिखित कमांड चला रहा हूं:

dd if=/dev/random of=rand bs=1K count=2

हालांकि, हर बार जब मैं इसे चलाता हूं, तो मैं एक अलग आकार की फ़ाइल के साथ समाप्त होता हूं। ऐसा क्यों है? मैं यादृच्छिक डेटा से भरे किसी दिए गए आकार की फ़ाइल कैसे बना सकता हूं?


1
/dev/randomयदि आप चाहते हैं कि अंकों की संख्या उत्पन्न करने के लिए पर्याप्त एन्ट्रापी उपलब्ध नहीं है तो ब्लॉक कर देगा। यह केवल उच्च गुणवत्ता वाले psuedo यादृच्छिक "यादृच्छिकता" की उस राशि को इकट्ठा करने में समय लेता है ... या तो /dev/urandomएक कम यादृच्छिक "यादृच्छिक" मूल्य के लिए उपयोग करें , या अपने एंट्रोपी पूल (एक लूप में, और आवश्यकतानुसार प्रतीक्षा करें) की जांच करें ...
पीटर


3
बस जोड़ेंiflag=fullblock
frostschutz

जवाबों:


31

आप ddलिनक्स के अजीब व्यवहार के साथ अजीब व्यवहार के संयोजन का अवलोकन कर रहे हैं /dev/random। दोनों, वैसे, शायद ही कभी नौकरी के लिए सही उपकरण हैं।

लिनक्स के /dev/randomडेटा का कम खर्च होता है। यह इस धारणा पर आधारित है कि छद्म आयामी संख्या जनरेटर में एन्ट्रापी बहुत तेज दर से बुझ जाती है। चूंकि नई एन्ट्रॉपी इकट्ठा करना धीमा है, /dev/randomआमतौर पर एक बार में केवल कुछ बाइट्स से छुटकारा मिलता है।

ddटेप डिवाइस पर काम करने के लिए शुरू में एक पुराना, क्रैंक प्रोग्राम है। जब आप इसे 1kB के एक ब्लॉक को पढ़ने के लिए कहते हैं, तो यह एक ब्लॉक को पढ़ने का प्रयास करता है। यदि रीड 1024 बाइट्स से कम रिटर्न देता है, तो यह कठिन है, बस इतना ही। तो dd if=/dev/random bs=1K count=2दो read(2)कॉल करता है। चूंकि यह पढ़ रहा है /dev/random, इसलिए दो readकॉल आम तौर पर केवल कुछ बाइट्स वापस करते हैं, उपलब्ध एंट्रोपी के आधार पर अलग-अलग संख्या में। यह भी देखें कि डेटा की प्रतिलिपि बनाने के लिए dd कब उपयुक्त है? (या, जब पढ़ा जाता है) और (आंशिक) लिखें

जब तक आप एक OS इंस्टॉलर या क्लोनर डिज़ाइन नहीं कर रहे हैं, आपको /dev/randomलिनक्स के तहत कभी भी उपयोग नहीं करना चाहिए /dev/urandomurandomआदमी पेज कुछ हद तक भ्रामक है; /dev/urandomवास्तव में क्रिप्टोग्राफी के लिए उपयुक्त है, यहां तक ​​कि लंबे समय तक रहने वाली चाबियाँ उत्पन्न करने के लिए। इसके साथ एकमात्र प्रतिबंध /dev/urandomयह है कि इसे पर्याप्त एंट्रोपी के साथ आपूर्ति की जानी चाहिए; लिनक्स वितरण आम तौर पर रिबूट के बीच एन्ट्रॉपी को बचाते हैं, इसलिए एक ही समय आपके पास पर्याप्त एन्ट्रापी नहीं हो सकता है जो एक नए इंस्टॉलेशन पर है। एन्ट्रॉपी व्यावहारिक रूप से नहीं पहनती है। अधिक जानकारी के लिए, पढ़ें क्या एक लॉगिन कुंजी के लिए / देव / यूरेनियम से रैंड सुरक्षित है? और दूध पिलाने / देव / यादृच्छिक एंट्रोपी पूल?

अधिकांश उपयोग ddबेहतर उपकरण जैसे headया के साथ व्यक्त किए जाते हैं tail। यदि आप यादृच्छिक बाइट्स के 2kB चाहते हैं, तो दौड़ें

head -c 2k </dev/urandom >rand

पुराने लिनक्स कर्नेल के साथ, आप दूर हो सकते हैं

dd if=/dev/urandom of=rand bs=1k count=2

क्योंकि /dev/urandomखुशी से अनुरोध के रूप में कई बाइट्स के रूप में लौट आए। लेकिन कर्नेल 3.16 के बाद से यह अब सच नहीं है, यह अब 32MB तक सीमित है

सामान्य तौर पर, जब आपको ddबाइट की एक निश्चित संख्या निकालने के लिए उपयोग करने की आवश्यकता होती है और इसका इनपुट एक नियमित फ़ाइल या ब्लॉक डिवाइस से नहीं आ रहा है, तो आपको बाइट द्वारा बाइट पढ़ने की आवश्यकता है dd bs=1 count=2048:।


डीडी के बजाय सिर का उपयोग करने पर टिप के लिए धन्यवाद। अगर मैं चाहूं तो मुझे अभी भी / dev / random का उपयोग करने की अनुमति देता है। हालाँकि, जैसा कि आप उल्लेख करते हैं / dev / urandom शायद पर्याप्त होगा, यह जानना अच्छा है कि कैसे उपयोग करना / dev / random की आवश्यकता उत्पन्न होनी चाहिए।
डैनियल

3.16 के बाद से गुठली पर /dev/urandom प्रति 32m रिटर्नread()
सुबह

वैकल्पिक रूप से, यदि आपको POSIX आज्ञाकारी कमांड की आवश्यकता है, तो आप यहाँ ट्रिक का उपयोग कर सकते हैं: unix.stackexchange.com/a/192114 dd if=/dev/urandom ibs=1k obs=1k | dd bs=1k count=2
रफ़लविंड

11

से man 4 randomएक RHEL 5 बॉक्स पर:

जब पढ़ा जाता है, तो / देव / यादृच्छिक उपकरण एंट्रॉपी पूल में शोर की बिट्स की अनुमानित संख्या के भीतर केवल यादृच्छिक बाइट्स लौटाएगा।

मुझे उस मशीन पर आकार 213 बाइट्स की फाइलें मिलती हैं। वापस आदमी के लिए 4 यादृच्छिक:

जब पढ़ा जाता है, / dev / urandom डिवाइस अनुरोध के रूप में कई बाइट्स के रूप में वापस आ जाएगी।

के हर आह्वान से मुझे 2048 बाइट मिलती हैं dd if=/dev/urandom of=rand bs=1K count=2

मैं यह निष्कर्ष निकालता हूं कि यह अंतर इस बात के कारण है कि आपकी मशीन कितने इनवॉइस के बीच उत्पन्न होती है dd if=/dev/random ...


हाँ, व्यावहारिक रूप से, जब तक कि वह एक वास्तविक क्रिप्टो अनुप्रयोग में न हो, @ डैनियल को / dev / urandom का उपयोग करना चाहिए। लेकिन मैं इस बात से हैरान हूं कि dd if=/dev/random bs=1K count=2जब एंट्रॉपी पूल में पानी की निकासी होती है, तो क्यों रुक जाता है। डॉक्स से, यह तब तक ब्लॉक होना चाहिए जब तक कि अधिक एंट्रॉपी न हो, इसलिए ddवर्तमान पूल को बाहर निकालने और बाहर निकलने के बजाय, धीरे-धीरे फ़ाइल को बाहर लिख देगा।
cjc

मैं इसके बारे में भी सोचता था, लेकिन यह आरएचईएल, स्लैकवेयर 13.1 और एक सुंदर वर्तमान आर्क के अनुरूप है। आरएचईएल x86_64 था, अन्य 32-बिट थे। दुर्भाग्य से dd डॉक्स GNU जानकारी प्रारूप में हैं, इसलिए मैंने उन सभी को नहीं पढ़ा है।
ब्रुक एडिगर

यह Gentoo पर भी सुसंगत है।
मैथ्यू शेर्ले

4
@cjc: ऐसा इसलिए है क्योंकि जब आप read(fd, mybuf, 1024)एक अवरुद्ध एफडी पर कॉल करते हैं तो जैसे ही अंतर्निहित डिवाइस कुछ डेटा लौटाता है । अगर वहाँ पढ़ने के लिए 1024 बाइट्स हैं, तो वह वापस आ जाता है। यदि केवल 201 बाइट्स हैं, तो यह 201 वापस आ जाएगी। यदि 0 बाइट्स उपलब्ध हैं, तो यह तब तक ब्लॉक रहेगा जब तक कम से कम एक बाइट उपलब्ध नहीं हो जाती है, तब इसे वापस कर दें।
वॉरेन यंग

@ArrenYoung अपनी सामग्री से / देव / यादृच्छिक नाली से पढ़ता है? मैं ऐसा मानता हूं।
माइकल मार्टिनेज

5

ddडेटा क्यों छोड़ता है ? ... गिल्स ने इस आकर्षक प्रश्न के बारे में बताया है dd:
dd डेटा की प्रतिलिपि बनाने के लिए उपयुक्त कब है? (या, जब पढ़ा जाता है () और लिखना () आंशिक)
यहाँ उस प्रश्न का एक अंश है:

    * - dd को गलती पर लगाना मुश्किल नहीं है; उदाहरण के लिए इस कोड को आज़माएं: **
        yes | dd of=out bs=1024k count=10
    और फ़ाइल के आकार की जांच करें (यह 10MB से कम होने की संभावना है)।


मेरी टिप्पणी के अलावा (आपके सवाल के अंत में), कुछ इस तरह से देखने के लिए परेशान है ... यह फ़ाइल में आपके बाइट्स को पकड़ता है $trnd। मैंने अर्ध-मनमाने ढंग से बी एस = 8 चुना है

अपने माउस को स्थानांतरित करें और इसे गति दें।
मेरे कंप्यूटर निष्क्रिय (AFK और कोई नेटवर्क गतिविधि) के साथ, और एंट्रोपी पूल को समाप्त करने के बाद, केवल 1192 बाइट्स एकत्र करने में 2 घंटे 12 मिनट का समय लगा , जिस बिंदु पर मैंने इसे रद्द कर दिया।

फिर, मेरे साथ माउस को लगातार घुमाते हुए, समान संख्या में बाइट इकट्ठा करने में अपेक्षाकृत कम 1 मिनट 15 सेकंड का समय लगा।

यह बहुत स्पष्ट रूप से दिखाता है कि एन्ट्रॉपी इकट्ठा करना सीपीयू की गति आधारित नहीं है, बल्कि यह यादृच्छिक घटनाओं पर आधारित है, और यह कि मेरा उबंटू सिस्टम माउस को इसके महत्वपूर्ण यादृच्छिक कारकों में से एक के रूप में उपयोग करता है।

get=2048
trnd=/tmp/$USER.rnd; >"$trnd"
while (( $(wc -c <"$trnd") < $get )) ;do
    dd if=/dev/random bs=8 count=1 2>/dev/null >>"$trnd"
    echo -n "itt: $((i+=1))  ct: "; wc -c <"$trnd"
done
truncate -s $get "$trnd"
echo -e "\nfinal count: "; wc -c <"$trnd"

1

ddहै डिज़ाइन किया गया चर आदानों आकार से पढ़ने के लिए यह आम तौर पर अपने निपटान में सबसे अच्छा उपकरण है आप इसे किया की जरूरत है - रोकने के लिए तुरंत क्योंकि ddवर्तमान बफ़र नहीं होगा कुछ भविष्य में पढ़ता है write() (जब तक आप बहुत स्पष्ट रूप से इसे IBS से बड़ा ओ बीएस साथ इस तरह से कॉन्फ़िगर) , लेकिन इसके बजाय write()यह सब कुछ पढ़ता है जैसे ही यह read()होगा (और वैकल्पिक रूप से इसे संसाधित करता है)

यहाँ कुछ महत्वपूर्ण परिभाषाएँ दी गई हैं :

  • ibs=expr
    • इनपुट ब्लॉक आकार निर्दिष्ट करें, बाइट्स में, (डिफ़ॉल्ट रूप से 512) हैexpr
  • obs=expr
    • आउटपुट ब्लॉक आकार निर्दिष्ट करें, बाइट्स में, (डिफ़ॉल्ट रूप से 512) हैexpr
  • bs=expr
    • इनपुट और आउटपुट ब्लॉक आकार दोनों को exprबाइट्स, सुपरस्डिंग ibs=और पर सेट करें obs=। कोई रूपांतरण के अलावा अन्य हैं sync, noerrorऔर notruncनिर्दिष्ट किया जाता है, प्रत्येक इनपुट ब्लॉक कम ब्लॉक के योग के बिना एक भी ब्लॉक के रूप में उत्पादन में कॉपी किया जाएगा।

तो आप देखते हैं, जब ibsऔर obsएक साथ परिभाषित कर रहे हैं के रूप में bsतो ibs, लेकिन अन्यथा यदि आप विशिष्ट हैं या तो फिर, - पहले हो सकती है obsया cbsनहीं करता है।

यहाँ एक उदाहरण है जिसमें ibsसबसे महत्वपूर्ण है। आप इस तरह से कुछ कर सकते हैं यदि आप ट्रैक करना चाहते थे कि /dev/randomपूल जल्द ही कैसे भरे ...

dd "ibs=$size" conv=sync "count=$lmt" \ 
    if=/dev/random of="$somefile"

जब तक if=लक्ष्य बिल्कुल ही पठनीय है, तब तक परिणाम हमेशा एक ही आकार की आउटपुट फ़ाइल के रूप में ddआएगा , क्योंकि syncब्लॉक रीड-इन नल पर hronize करेगा । दूसरे शब्दों में, यदि बार के dd read()इनपुट-ब्लॉक के लिए s $((size=10)) $((count=5))और read()फाइल 2 बाइट्स देता है, तो 8 बाइट्स, फिर 12 बाइट्स, फिर 2 बाइट्स, फिर 4 बाइट्स, ddजैसे उसके आउटफिट को कुछ लिखेंगे

 2 read bytes 8NULs \
 8 read bytes 2NULs \
10 read bytes 0NULs \
 4 read bytes 6NULs \
 4 read bytes 6NULs

... क्योंकि dd, डिफ़ॉल्ट रूप से, देरी नहीं करता है । इसलिए अगर आपको इन-स्ट्रीम को ट्रैक करने और किसी अन्य प्रक्रिया के लेखन को सीमांकित करने की आवश्यकता है, तो आपके ddलिए उपकरण है।

यदि आप अभी कुछ मात्रा में एक नियमित फ़ाइल के लिए लिख रहे हैं, तो यहां दिए गए अन्य कथनों के विपरीत, आप इसके लिए भी उपयोग कर सकते हैं dd- और काफी आसानी से - लेकिन आपको एक से अधिक और विश्वसनीय अवरोधक कारक की आवश्यकता होगी

उदाहरण के लिए, यदि आपने किया:

{   dd ibs="$size" obs="${size}x$block_factor" |
    dd bs="${size}x$blockfactor" "count=$lmt"
}  <infile >outfile

... पहला इनपुट ddबफ़र के रूप में कई ibs="$size"इनपुट ब्लॉक के रूप में आवश्यक होगा कि इसके और पाइप के बीच obs="${size}x$block_factor"हर write()पाइप के लिए कम से कम एक आउटपुट ब्लॉक भरना आवश्यक हो dd। इसका मतलब यह है कि दूसरा ddउत्पादन को मज़बूती से सीमित कर सकता है count="$lmt"क्योंकि पहले किए गए सभी write()एस अपने i / o ब्लॉकचेज़ से मेल खाएंगे - भले ही इसे बनाने के read()लिए पहले कितने एस को ddकरना पड़े।

और यह कि आप ddकेवल थोड़ी सी गणित के साथ पाइप या अन्य प्रकार की विशेष फ़ाइलों को मज़बूती से पढ़ने के लिए कैसे उपयोग कर सकते हैं ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.