2011-12-21 8 views
6

मेरे कोड में, मुझे सीआरसी 32 सहित विभिन्न एल्गोरिदम का उपयोग करके हैश फाइलों की आवश्यकता है। चूंकि मैं Digest परिवार में अन्य क्रिप्टोग्राफिक हैश फ़ंक्शंस का भी उपयोग कर रहा हूं, मैंने सोचा कि उन सभी के लिए एक सतत इंटरफेस बनाए रखना अच्छा होगा।डाइजेस्ट :: सीआरसी 32 ज़्लिब

रिकॉर्ड के लिए, मुझे digest-crc मिला, एक मणि जो वास्तव में मैं चाहता हूं। बात यह है कि, Zlib मानक पुस्तकालय का हिस्सा है और इसमें सीआरसी 32 का एक कार्यान्वयन कार्यान्वयन है जिसे मैं पुन: उपयोग करना चाहता हूं। इसके अलावा, यह सी में लिखा गया है, इसलिए इसे digest-crc के संबंध में बेहतर प्रदर्शन प्रदान करना चाहिए, जो शुद्ध-रूबी कार्यान्वयन है।

Digest::CRC32 को लागू वास्तव में पहली बार में बिल्कुल स्पष्ट देखा:

%w(digest zlib).each { |f| require f } 

class Digest::CRC32 < Digest::Class 
    include Digest::Instance 

    def update(str) 
    @crc32 = Zlib.crc32(str, @crc32) 
    end 

    def initialize; reset; end 
    def reset; @crc32 = 0; end 
    def finish; @crc32.to_s; end 
end 

सब कुछ सही लग रहा है:

crc32 = File.open('Rakefile') { |f| Zlib.crc32 f.read } 
digest = Digest::CRC32.file('Rakefile').digest!.to_i 
crc32 == digest 
=> true 

दुर्भाग्य से, नहीं सब कुछ काम करता है:

Digest::CRC32.file('Rakefile').hexdigest! 
=> "313635393830353832" 

# What I actually expected was: 
Digest::CRC32.file('Rakefile').digest!.to_i.to_s(16) 
=> "9e4a9a6" 

hexdigest मूल रूप से रिटर्न Digest.hexencode(digest), 012,330,। मुझे यकीन नहीं है कि यह फ़ंक्शन कैसे काम करता है, इसलिए मैं सोच रहा था कि Zlib.crc32 से वापस पूर्णांक के साथ इसे प्राप्त करना संभव है या नहीं। यह वास्तव में अपने प्रश्न का उत्तर नहीं है, लेकिन यह मदद कर सकता है ..

सबसे पहले, जब एक फ़ाइल में पढ़ने, सुनिश्चित करें कि आप "rb" पैरामीटर पारित कर

+0

क्या माणिक मंच पर आप काम कर रहे हैं? – 2potatocakes

+0

@ 2potatocakes, सी रूबी 1.9.3। –

उत्तर

6

डाइजेस्ट कच्चे बाइट्स को लौटने के लिए पचाने की उम्मीद कर रहा है जो चेकसम बनाते हैं, यानी एक crc32 के मामले में 4 बाइट जो 32 बिट पूर्णांक मेकअप करते हैं। हालांकि आप इसके बजाय एक स्ट्रिंग लौट रहे हैं जिसमें उस पूर्णांक का आधार 10 प्रतिनिधित्व शामिल है।

आप

[@crc32].pack('V') 

की तरह कुछ बाइट्स है कि प्रतिनिधित्व में है कि पूर्णांक चालू करना चाहते हैं।जाओ और पैक और उसके विभिन्न प्रारूप विनिर्देशकों पर पढ़ें - बाइट्स को देशी एंडियन-नेस, बड़े-एंडियन, छोटे-एंडियन आदि में प्रस्तुत किया जाना चाहिए, इस पर निर्भर करते हुए एक पूर्णांक पैक करने के कई तरीके हैं ताकि आपको पता लगाना चाहिए कि कौन सा पता लगाना चाहिए एक अपनी आवश्यकताओं

+1

मैंने उम्मीद के अनुसार काम करने के लिए Digest :: CRC32.file (फ़ाइल नाम) का अपना संस्करण प्राप्त करने के लिए [@ crc32] .pack ('n') का उपयोग किया। –

3

क्षमा करें। मैं तुम्हें खिड़कियों पर नहीं कर रहे हैं, लेकिन अगर संयोग से अपने कोड हो रही अंत करता है एक विंडोज़ मशीन पर दौड़ा अपने कोड एक ही है, खासकर जब में माणिक फ़ाइलें पढ़ने काम नहीं करेगा देख सकते हैं उदाहरण:।

crc32 = File.open('test.rb') { |f| Zlib.crc32 f.read } 
#=> 189072290 
digest = Digest::CRC32.file('test.rb').digest!.to_i 
#=> 314435800 
crc32 == digest 
#=> false 

crc32 = File.open('test.rb', "rb") { |f| Zlib.crc32 f.read } 
#=> 314435800 
digest = Digest::CRC32.file('test.rb').digest!.to_i 
#=> 314435800 
crc32 == digest 
#=> true 

उपरोक्त सभी प्लेटफार्मों और सभी rubies में काम करेगा .. मुझे पता है .. लेकिन यह नहीं है कि आपने क्या पूछा ..

मुझे यकीन है कि आपके उपर्युक्त उदाहरण में हेक्सडिजिस्ट और डाइजेस्ट विधियां काम कर रही हैं, हालांकि उन्हें ..

dig_file = Digest::CRC32.file('test.rb') 

test1 = dig_file.hexdigest 
#=> "333134343335383030" 

test2 = dig_file.digest 
#=> "314435800" 

def hexdigest_to_digest(h) 
    h.unpack('a2'*(h.size/2)).collect {|i| i.hex.chr }.join 
end 

test3 = hexdigest_to_digest(test1) 
#=> "314435800" 

तो मैं अनुमान लगा रहा हूं th .i_i.to_s (16) आपके अपेक्षित परिणाम को फेंक रहा है या आपका अपेक्षित परिणाम संभवतः गलत हो सकता है? निश्चित नहीं है, लेकिन सभी बेहतरीन

+0

आप वहां कुछ पर हैं; मुझे लगता है कि इसका जवाब इसके विपरीत है: हेक्सडिजिस्ट को पचाना। मैंने बेस 16 को मजबूर करने की कोशिश करने से पहले 'अनपॅक' के साथ कुछ करने की कोशिश की लेकिन वास्तव में मुझे नहीं पता था कि मैं क्या कर रहा था। मैं अभी भी इसे समझ में नहीं आता। –

+0

'डाइजेस्ट' "सही" चेकसम आउटपुट करता है क्योंकि यह केवल 'फिनिश' विधि देता है जो देता है। हकीकत में, इसे 'डाइजेस्ट.हेक्सनकोड' के लिए उपयुक्त एक बाइनरी स्ट्रिंग वापस करनी चाहिए, जो हेक्साडेसिमल में बाइट को एन्कोड करना चाहिए। तो हाँ, ऐसा लगता है कि मेरी विधियां टूट गई हैं। :) –

3

यह सिर्फ ठीक काम करता है से मेल खाता है, इस तरह, हमेशा नेटवर्क बाइट क्रम का उपयोग सुनिश्चित करें:

def finish; [@crc32].pack('N'); end