2011-02-17 20 views
5

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

इनमें से कुछ तारों को दो बार यूटीएफ -8 में एन्कोड किया जाएगा।

मुझे विश्वसनीय रूप से पता लगाना चाहिए कि क्या दिया गया स्ट्रिंग डबल-एन्कोड किया गया है, और इसे ठीक करें। मुझे बाइट्स का निरीक्षण करके, बाहरी पुस्तकालयों का उपयोग किए बिना ऐसा करना चाहिए। पहचान जितनी जल्दी हो सके होना चाहिए।

सवाल यह है कि: यह पता लगाने के लिए कि किसी दिए गए स्ट्रिंग को यूटीएफ -8 में दो बार एन्कोड किया गया था?

अद्यतन:

मूल तार UTF-8 में कर रहे हैं। यहाँ AS3 कोड है कि दूसरी एन्कोडिंग करता है (दुर्भाग्य से मैं ग्राहक कोड पर नियंत्रण नहीं है, तो मैं इसे ठीक नहीं कर सकता):

private function toUTF8(s : String) : String { 
     var byteArray : ByteArray = new ByteArray(); 
     byteArray.writeUTFBytes(s); 
     byteArray.position = 0; 

     var res : String = ""; 

     while(byteArray.bytesAvailable){ 
      res += String.fromCharCode(byteArray.readUnsignedByte()); 
     } 

     return res; 
} 

myString = toUTF8(("" + myString).toLowerCase().substr(0, 64)); 

नोट toLowerCase() कॉल। शायद यह मदद कर सकता है?

+1

आपका क्या मतलब है डबल UTF8 में एन्कोड द्वारा? ? –

+2

@Martin: Fwiw, मेरा उत्तर मान लिया गया है इसका मतलब है कि एन्कोडिंग एक्स में पाठ लेते हैं, यह UTF-8 बाइट्स को बदलने, तो उन बाइट्स लेते हैं, उन्हें एन्कोडिंग एक्स के रूप में पुनर्व्याख्या और UTF-8 बाइट्स को बदलने कि। दूसरे शब्दों में, क्या होता है जब आप गलत तरीके से ISO-8859-1 (या जो भी) के रूप में एक UTF-8 फ़ाइल फ़ाइल की व्याख्या और फिर "यह UTF-8 में बदलें"। –

+0

ठीक है, मूल पाठ यूटीएफ -8 में था, और इसे एक बार फिर बग्गी क्लाइंट लाइब्रेरी द्वारा यूटीएफ -8 में एन्कोड किया गया है। मैं मूल तार पर नियंत्रण की जरूरत नहीं है (मैं क्या एन्कोडिंग कि पुस्तकालय पाठ ग्रहण में था के बारे में अधिक जानकारी प्राप्त करने की कोशिश करेंगे।) –

उत्तर

4

सिद्धांत रूप में आप विशेष रूप से बिल्ली-कचरे की अनुमति नहीं दे सकते हैं।

आप यह नहीं कहते कि डेटा का मूल वर्ण एन्कोडिंग यूटीएफ -8 एन्कोडेड होने से पहले एक या दो बार था। मैं CP1251 मानूंगा, (या कम से कम वह CP1251 संभावनाओं में से एक है) क्योंकि यह काफी मुश्किल मामला है।

एक गैर-ASCII चरित्र लें। यूटीएफ -8 इसे एन्कोड करें। आपको कुछ बाइट मिलते हैं, और उन सभी बाइट्स सीपी 1251 में मान्य वर्ण हैं जब तक कि उनमें से कोई 0x 9 8 न हो, सीपी 1251 में एकमात्र छेद।

तो, यदि आप उन बाइट्स को सीपी 1251 से यूटीएफ -8 में परिवर्तित करते हैं, तो परिणाम बिल्कुल वैसा ही होगा जैसा कि आप सही ढंग से यूटीएफ -8 को उन रूसी अक्षरों वाली सीपी 1251 स्ट्रिंग को एन्कोड किया होगा। यह बताने का कोई तरीका नहीं है कि परिणाम गलत रूप से डबल-एन्कोडिंग एक वर्ण, या सही ढंग से एकल-एन्कोडिंग 2 वर्णों से है या नहीं।

यदि आपके मूल डेटा पर कुछ नियंत्रण है, तो आप इसकी शुरुआत में बीओएम डाल सकते हैं। फिर जब यह आपके पास आता है, तो शुरुआती बाइट्स का निरीक्षण यह देखने के लिए करें कि क्या आपके पास यूटीएफ -8 बीओएम है, या बीओएम गलत तरीके से डबल-एन्कोडिंग का परिणाम है। लेकिन मुझे लगता है कि शायद आपके पास मूल पाठ पर उस तरह का नियंत्रण नहीं है।

अभ्यास आप अनुमान लगा सकते हैं - UTF-8 यह डीकोड और उसके बाद:

(क) चरित्र आवृत्तियों को देखो, चरित्र जोड़ी आवृत्तियों, प्रिंट न हो सकने पात्रों की संख्या। यह आपको इसे बकवास घोषित करने की अनुमति दे सकता है, और इसलिए संभवतः डबल-एन्कोडेड। पर्याप्त गैर-प्रिंट करने योग्य पात्रों के साथ यह इतना बकवास हो सकता है कि आप वास्तव में कीबोर्ड पर मैशिंग करके इसे टाइप नहीं कर सकते हैं, जब तक कि आपकी एएलटी कुंजी फंसे न हो।

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

यदि आपके पास कुछ बाइट्स हैं जो यूटीएफ -8 हो सकते हैं या सीपी 1251 हो सकते हैं, तो आप कम या कम क्या करते हैं, और आप नहीं जानते कि कौन सा है।

आपको डबल-एन्कोडेड डेटा से अलग-अलग एकल-एन्कोडेड बिल्ली-कचरा के लिए कुछ झूठे सकारात्मक मिलेगा, और शायद डबल-एन्कोड किए गए डेटा के लिए बहुत कम झूठी नकारात्मकताएं होंगी लेकिन फिर भी फ्लेक द्वारा पहले एन्कोड के बाद रूस।

यदि आपके मूल एन्कोडिंग में CP1251 की तुलना में इसमें अधिक छेद हैं तो आपके पास कम झूठे नकारात्मक होंगे।

कैरेक्टर एन्कोडिंग कठिन हैं।

+0

आप सही हैं,। लेकिन मैंने अधिक जानकारी के साथ प्रश्न अपडेट किया है, शायद इससे मदद मिलेगी। –

2

यहां एक PHP एल्गोरिदम है जो मेरे लिए काम करता है।

यह अपने डेटा को ठीक करने के लिए बेहतर है, लेकिन अगर तुम यहाँ नहीं कर सकते हैं एक चाल है:

if (mb_detect_encoding(utf8_decode($value)) === 'UTF-8') { 
    // Double encoded, or bad encoding 
    $value = utf8_decode($value); 
} 

$value = \ForceUTF8\Encoding::toUTF8($value); 

पुस्तकालय मैं उपयोग कर रहा हूँ है: https://github.com/neitanod/forceutf8/

+1

यह काम करता है - असल में - बहुत अच्छा – bhelm

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