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 में डालने वाली प्रक्रिया को देखना चाहिए, और यह सुनिश्चित करना चाहिए कि यह एन्कोडिंग को सही तरीके से संभालता है।
मैंने उसकेोकू प्रयोगशाला रूबी 1.9.3 के माध्यम से स्थापित किया, लेकिन मुझे अभी भी वही त्रुटि मिलती है: | – klaut
रूबी में Iconv की आवश्यकता होने पर 1.9.3 आपको यह चेतावनी मिलती है: 'आइकनव को भविष्य में बहिष्कृत किया जाएगा, इसके बजाय स्ट्रिंग # एन्कोड का उपयोग करें।' आपके समाधान के बराबर कुछ ऐसा होगा: 'string.force_encoding (' iso-8859- 1 ')। सांकेतिक शब्दों में बदलना (' utf-8 ') '। – matt
या 'string = message.encode ('utf-8', 'iso-8859-1') 'बेहतर हो सकता है। – matt