2012-04-06 17 views
11

मेरे पास रेडिस में टेक्स्ट संदेश की कतार है। आइए मान लें कि रेडिस में एक संदेश ऐसा कुछ है:यूटीएफ -8 त्रुटि में रेल, हेरोकू और अमान्य बाइट अनुक्रम

"niño" 

(गैर मानक चरित्र को स्पॉट करें)।

रेल ऐप संदेशों की कतार प्रदर्शित करता है। जब मैं स्थानीय रूप से परीक्षण करता हूं (रेल 3.2.2, रूबी 1.9.3) सबकुछ ठीक है, लेकिन हेरोोकू सीडर (रेल 3.2.2, मुझे लगता है कि रूबी 1.9.2 है) मुझे कुख्यात त्रुटि मिलती है: ActionView::Template::Error (invalid byte sequence in UTF-8)

मैं ऑनलाइन खोज सकता हूं और पढ़ रहा हूं, मैं अभी भी इसे ठीक करने के तरीके के रूप में अटक गया हूं।

सही दिशा में कोई मदद या बिंदु बहुत सराहना की है!

संपादित करें:

मुझे एक समाधान खोजने में कामयाब रहा।

string = Iconv.iconv('UTF-8', 'ISO-8859-1', message)[0] 

सुझाव दिया जवाब मैं आसपास पाया में से कोई भी मेरे मामले में काम करने के लिए लग रहे हैं: मैं iconv का उपयोग कर समाप्त हो गया।

+0

मैंने उसकेोकू प्रयोगशाला रूबी 1.9.3 के माध्यम से स्थापित किया, लेकिन मुझे अभी भी वही त्रुटि मिलती है: | – klaut

+2

रूबी में Iconv की आवश्यकता होने पर 1.9.3 आपको यह चेतावनी मिलती है: 'आइकनव को भविष्य में बहिष्कृत किया जाएगा, इसके बजाय स्ट्रिंग # एन्कोड का उपयोग करें।' आपके समाधान के बराबर कुछ ऐसा होगा: 'string.force_encoding (' iso-8859- 1 ')। सांकेतिक शब्दों में बदलना (' utf-8 ') '। – matt

+2

या 'string = message.encode ('utf-8', 'iso-8859-1') 'बेहतर हो सकता है। – matt

उत्तर

38

Heroku, अपने ऐप के Redis से संदेश "नीनो" प्राप्त करता है, यह वास्तव में हो रही है चार बाइट्स:

0x6e 0x69 0xf1 0x6f 

, जो जब ISO-8859-1 के रूप में व्याख्या पात्रों के अनुरूप n, i, ñ और o

हालांकि, आपके रेल ऐप मानते हैं कि इन बाइट्स को UTF-8 के रूप में व्याख्या किया जाना चाहिए, और किसी बिंदु पर यह उन्हें इस तरह से डीकोड करने का प्रयास करता है। इस क्रम में तीसरे बाइट, 0xf1 इस तरह दिखता है:

1 1 1 1 0 0 0 1 

आप table on the Wikipedia page को यह तुलना, तो आप देख सकते हैं इस बाइट एक चार बाइट वर्ण की अग्रणी बाइट है (यह पैटर्न 11110xxx से मेल खाता है), और क्योंकि इसके बाद तीन और निरंतर बाइट्स का पालन किया जाना चाहिए जो सभी पैटर्न 10xxxxxx से मेल खाते हैं। ऐसा नहीं है, इसके बजाय अगला बाइट 0x6f (01101111) है, और इसलिए यह अमान्य utf-8 बाइट अनुक्रम है और आपको जो त्रुटि दिखाई देती है वह आपको मिलती है।

का उपयोग करना:

string = message.encode('utf-8', 'iso-8859-1') 

(या Iconv समकक्ष) रूबी बताता message पढ़ने के लिए ISO-8859-1 इनकोडिंग के रूप में, और उसके बाद UTF-8 एन्कोडिंग में बराबर स्ट्रिंग है जिसे आप उपयोग कर सकते हैं बनाने के लिए बिना किसी समस्या के। (स्ट्रिंग के सही एन्कोडिंग रूबी को बताने के लिए force_encoding का उपयोग करने का एक विकल्प हो सकता है, लेकिन जब आप यूटीएफ -8 और आईएसओ -885 9 -1 तारों को मिश्रण करने का प्रयास करेंगे तो इससे समस्याएं बाद में हो सकती हैं)।

UTF-8 में, स्ट्रिंग "नीनो" बाइट्स से मेल खाती है:

0x6e 0x69 0xc3 0xb1 0x6f 

ध्यान दें कि प्रथम, द्वितीय और आखिरी बाइट एक ही हैं। ñ वर्ण को दो बाइट 0xc3 0xb1 के रूप में एन्कोड किया गया है।यदि आप बाइनरी में इन्हें लिखते हैं और विकिपीडिया में तालिका की तुलना में फिर से लेख में देखते हैं तो आप देखेंगे कि वे 0xf1 एन्कोड करते हैं, जो ñ का आईएसओ -885 9 -1 एन्कोडिंग है (क्योंकि पहले 256 यूनिकोड कोडपॉइंट्स आईएसओ -885 9 -1 से मेल खाते हैं) ।

आप इन पांच बाइट्स लेते हैं और उन्हें किया जा रहा है ISO-8859-1 के रूप में इलाज है, तो वे स्ट्रिंग

niño 

ISO-8859-1 codepage को देखते हुए, 0xc3 Â के नक्शे, और 0xb1 नक्शे ± करने के अनुरूप हैं।

तो आपकी स्थानीय मशीन पर क्या हो रहा है यह है कि आपका ऐप रेडिस से पांच बाइट 0x6e 0x69 0xc3 0xb1 0x6f प्राप्त कर रहा है, जो "निनो" का यूटीएफ -8 प्रतिनिधित्व है। हेरोकू पर यह चार बाइट 0x6e 0x69 0xf1 0x6f प्राप्त कर रहा है, जो आईएसओ -885 9 -1 प्रतिनिधित्व है।

आपकी समस्या का असली समाधान यह सुनिश्चित करना होगा कि रेडिस में तारों को रखा जा रहा है, सभी पहले से ही यूटीएफ -8 (या कम से कम सभी समान एन्कोडिंग) हैं। मैंने रेडिस का उपयोग नहीं किया है, लेकिन मैं एक संक्षिप्त Google से जो कुछ कह सकता हूं, उससे स्ट्रिंग एन्कोडिंग के साथ खुद को चिंता नहीं होती है, लेकिन यह जो भी बाइट दिया गया है उसे वापस देता है। आपको डेटा को Redis में डालने वाली प्रक्रिया को देखना चाहिए, और यह सुनिश्चित करना चाहिए कि यह एन्कोडिंग को सही तरीके से संभालता है।

+0

में परिवर्तित करने के लिए करता हूं। +1 – coreyward

+0

बहुत अच्छा जवाब, धन्यवाद! – klaut

+2

वाह, इस तरह उत्तर दिखने चाहिए! – Cristian

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

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