2011-07-25 15 views
15

मेरे पास ऐसी साइट है जिसे सर्वर पर अपलोड की गई बाइनरी फ़ाइलों को एन्क्रिप्ट और स्टोर करने की आवश्यकता है। अपलोड करने और भंडारण ठीक काम करता है, लेकिन मैं जब एन्क्रिप्टेड फ़ाइल लिखने की कोशिश कर इस त्रुटि हो रही है:एन्कोडिंग :: अपरिभाषित कनवर्सन एक बाइनरी फ़ाइल लिखते समय त्रुटि

एन्कोडिंग :: UndefinedConversionError ("\ xDD" ASCII-8bit से UTF-8 में):

कोड है कि कारण बनता है यह इस तरह दिखता है:

fd_in = IO.sysopen(self[:name].tempfile.path, "rb")       
file_in = IO.open(fd_in)              
fd_out = IO.sysopen(self[:name].tempfile.path + ".encrypted", "wb")   
file_out = IO.open(fd_out)              
cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')       
cipher.encrypt                           
cipher.key = cipher_key              
cipher.iv = cipher_iv              
while chunk = file_in.read(1024)            
    file_out << cipher.update(chunk)            
end 
file_out << cipher.final 

लाइन है कि कारण बनता त्रुटि file_out < < cipher.update (हिस्सा), जबकि पाश में है। मैंने इस ऑनलाइन में देखा है और समान ASCII/UTF रूपांतरण समस्याओं की कुछ रिपोर्टें पाई हैं, लेकिन वे सभी कोरिंग स्ट्रिंग इनपुट पर आधारित हैं, स्ट्रीम फ़ाइल इनपुट नहीं। मैं रूबी 1.9.2 का उपयोग कर रहा हूं जो मुझे विश्वास है कि डिफ़ॉल्ट स्ट्रिंग एन्कोडिंग को प्रभावित करता है।

मेरा तर्क क्यों है (मुझे लगता है) मुझे स्ट्रीम-आधारित दृष्टिकोण का उपयोग करने की आवश्यकता है: फाइलें बड़ी होती हैं और मैं इसे संसाधित करने के लिए पूरी फ़ाइल (इनपुट या आउटपुट) को स्मृति में लोड नहीं करना चाहता हूं।

किसी भी मदद की सराहना की जाती है। धन्यवाद।

+0

मैं पाया है कि का उपयोग कर .force_encoding ("UTF-8") #update और #final कॉल पर इस मुद्दे को हल करता है। यदि कोई इस बात का वजन कर सकता है कि यह वास्तव में ऐसा करने का सही तरीका है और यदि (क्यों?) यूटीएफ -8 स्वीकार्य है, तो मुझे जानना अच्छा लगेगा। –

+0

इसके लायक होने के लिए, मैंने एन्कोडिंग.default_external और Encoding.default_internal भी जांच की है और दोनों यूटीएफ -8 हैं। –

उत्तर

27

आप जब एन/decrypting इलाज इनपुट और कच्चे बाइट्स के रूप में उत्पादन होता है क्या करना चाहते हैं क्या, आप सभी कीमत पर अपने डेटा के साथ कोई एन्कोडिंग जोड़ की वजह से कोई ट्रांसकोडिंग बचना चाहते हैं। इसलिए आपको अपनी फाइलें पढ़ने और लिखने के लिए दोनों बाइनरी मोड में खोलनी चाहिए।

वास्तव में आप इस किया था, लेकिन आईओ # sysopen साथ है, लेकिन फिर आप जब आईओ # खुला का उपयोग कर "बी" झंडे खरा नहीं उतरा। यदि आप इसके बजाय इस कोशिश

आपका कोड काम करना चाहिए:

fin = File.open("TODO", "rb")       
fout = File.open("TODO.encrypted", "wb")   
cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc') 
cipher.encrypt      
cipher.key = key              
cipher.iv = iv              
while chunk = fin.read(1024)            
    fout << cipher.update(chunk)            
end 
fout << cipher.final 
fin.close 
fout.close 
+0

आह - मैंने माना (गलत तरीके से) कि IO # खुला #sysopen से फ़ाइल वर्णनकर्ता के मोड का उपयोग करेगा। धन्यवाद! –

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