स्ट्रिंग को छोटा बनाने के लिए मैं किस प्रकार के एन्कोडिंग का उपयोग कर सकता हूं?


13

मेरे पास एक स्ट्रिंग एन्कोडिंग में दिलचस्पी है और मैं उत्सुक हूं यदि एक प्रकार की एन्कोडिंग है जिसका उपयोग किया जा सकता है जिसमें केवल अल्फा और न्यूमेरिक वर्ण शामिल होंगे और स्ट्रिंग का प्रतिनिधित्व करने के लिए आवश्यक वर्णों की संख्या को कम कर देंगे।

अब तक मैंने ऐसा करने के लिए बेस 64 एन्कोडिंग का उपयोग किया है, लेकिन यह मेरे तार को लंबे समय तक बनाने के लिए प्रतीत होता है और कभी-कभी इसमें शामिल होता है ==जिससे मैं बचना चाहूंगा। उदाहरण:

परीक्षण नाम | 120101 |

हो जाता है

dGVzdCBuYW1lfDEyMDEwMQ ==

जो 16 से 24 वर्णों तक जाता है और इसमें गैर-अल्फ़ान्यूमेरिक शामिल होता है।

क्या किसी को विभिन्न प्रकार के एन्कोडिंग के बारे में पता है जो मैं उपयोग कर सकता हूं जो मेरी आवश्यकताओं को प्राप्त करेगा? बोनस अंक अगर यह या तो .NET फ्रेमवर्क में बनाया गया है या तीसरे पक्ष के पुस्तकालय में मौजूद है जो एन्कोडिंग करेगा।


1
हफ़मैन कोडिंग की तरह नुकसान कम संपीड़न का उपयोग नहीं कर सकते हैं !! वे आदर्श रूप से ग्रंथों के लिए अनुकूल हैं ... लेकिन फिर अंत में आपको इस म्यूटेशन के बारे में जानना चाहिए जो आपने पाठ को वापस पाने के लिए किया है।

6
आप संपीड़न का वर्णन कर रहे हैं, एन्कोडिंग नहीं
एंडी स्मिथ

@ और - ठीक है, कोई सुझाव?
अबे मिसेलर

जवाबों:


30

Base64 में अंतिम '=' या '==' केवल वर्णों की संख्या को 4 बनाने के लिए है। आप इसे हटा सकते हैं, क्योंकि आप इसे हमेशा बाद में वापस रख सकते हैं। ध्यान दें कि बेस 64 को कहा जाता है क्योंकि यह 64 अलग-अलग वर्णों का उपयोग करता है । अपरकेस अक्षर, लोअरकेस अक्षर और अंक, यह 62 है। तो बेस 64 भी '/' और '+' का उपयोग करता है, जो आपके बिल में फिट हो भी सकता है और नहीं भी।

एक सामान्य आधार पर, यदि आप बाइट्स के मनमाने अनुक्रमों को अल्फ़ान्यूमेरिक वर्णों में बदलना चाहते हैं, तो आवश्यक रूप से कहीं न कहीं लंबाई विस्तार है, क्योंकि बाइट के लिए 256 संभव मान हैं, और केवल 62 अल्फ़ान्यूमेरिक वर्ण हैं। इसे कभी-कभी कबूतर सिद्धांत कहा जाता है । एन्कोडिंग योजना में फैक्टर लॉग 256 / लॉग 62 = 1.344 की औसत लंबाई का विस्तार होना चाहिए (बाइट्स के सभी क्रमों पर औसत); अन्यथा, इसका मतलब है कि कुछ कबूतरों को कहीं न कहीं मौत के घाट उतारा जा रहा है और आप उन्हें नुकसान के बिना वापस नहीं लेंगे (जिसका अर्थ है: दो अलग-अलग तार एक ही साथ एन्कोडेड हैं, इसलिए डिकोडिंग मज़बूती से काम नहीं कर सकते हैं)।

अब, यह काफी संभव है कि आपके तार "समान रूप से यादृच्छिक बाइट्स के अनुक्रम" नहीं हैं; आपके तार का कुछ अर्थ है जिसका अर्थ है कि बाइट्स का सबसे संभव अनुक्रम नहीं होगा, क्योंकि वे अर्थहीन हैं। उस आधार पर, आप संभवतः एक एन्कोडिंग योजना तैयार कर सकते हैं, जो सामान्य बेस 64 (या बेस 62 की तुलना में कम लंबाई के विस्तार को उकसाएगी यदि आपको सख्त अल्फ़ान्यूमेरिक वर्णों से चिपके रहने की आवश्यकता है)। यह दोषरहित डेटा संपीड़न है । यह स्पष्ट रूप से परिभाषित संभाव्य मॉडल पर काम करता है जो इनपुट के रूप में प्रकट हो सकता है।

सारांश: अल्फ़ान्यूमेरिकल अनुक्रमों में तारों को कूटने के लिए एक सामान्य योजना जैसे कि कोई या थोड़ी लंबाई का विस्तार कभी भी नहीं हो सकता; यह एक गणितीय असंभव है। आपके द्वारा अपेक्षित इनपुट स्ट्रिंग के लिए एक विशिष्ट योजना संभवतया मौजूद हो सकती है (लेकिन चूंकि आप यह नहीं बताते हैं कि आप किस प्रकार की स्ट्रिंग का सामना कर सकते हैं, कोई भी इस पर आपकी सहायता नहीं कर सकता है)।


1
+1, उत्कृष्ट व्याख्या। मुझे पता नहीं था =/ ==होने के बारे में पता किया जा रहा है कि लंबाई 4. से अधिक है। मैं अपनी जरूरतों के लिए इस के आसपास काम करने में सक्षम हो सकता हूं
अबे मिसेलर

ध्यान रहे, यह कबूतरों की कमी को मानता है। यूनिकोड के पास बहुत सारे पत्र हैं। हमें वास्तव में वास्तविक समस्या की बेहतर समझ की आवश्यकता है।
15

@ आप लॉग डिवीजन का उपयोग करके औसत लंबाई विस्तार कारक की गणना कैसे करते हैं? En.wikipedia.org/wiki/Base64 में आरेख के आधार पर यह पूरी तरह से सहज ज्ञान युक्त बनाता है कि प्रत्येक अनएन्कोडर्ड चार के लिए यह बेस 64 में 4/3 चार्ट का प्रतिनिधित्व करता है। बस सोच रहा था कि आप गणित के साथ एक ही निष्कर्ष पर कैसे आए ... धन्यवाद :)
जोनाथन लिन

मेरा बुरा, बेवकूफ सवाल। log (256) = 8 बिट्स, लॉग (64) = 6 बिट्स, इसलिए Base64 के लिए अनुपात 8/6 = 4/3 = 1.333 है। चीयर्स।
जोनाथन लिन

4

री-एन्कोडिंग वर्ण आम तौर पर तब किए जाते हैं जब प्राप्त प्रणाली उन्हें संसाधित नहीं कर सकती है। उदाहरण के लिए, BASE64 लंबे डेटा अनुक्रम (कभी-कभी दिखने वाला "==" अंत में संरेखण के लिए पैडिंग है) का प्रतिनिधित्व करने के लिए 6 बिट्स (2 6 , इसलिए 64) वर्णों का उपयोग करके डेटा का प्रतिनिधित्व कर रहा है। ऐसा इसलिए है क्योंकि ईमेल में आपकी चित्र फ़ाइल में 0xFE हो सकता है और आपका मेल सर्वर उस (या किसी अन्य पारंपरिक रूप से गैर-मुद्रण वर्ण) को प्रसारित करने से नाखुश होगा।

कोई एन्कोडिंग नहीं है जो "आकार को कम करता है।" एनकोडिंग केवल उस चरित्र के लिए बिट्स की मैपिंग हैं जो वे प्रतिनिधित्व करते हैं। उस ने कहा, ASCII एक 7 बिट कैरेक्टर सेट (एन्कोडिंग) है जिसे अक्सर 8 बिट्स स्पेस में स्टोर किया जाता है। यदि आप उन सीमाओं को सीमित करते हैं जिन्हें आप स्वीकार करते हैं, तो आप नियंत्रण वर्णों को भी मातम कर सकते हैं।

इस पद्धति का उपयोग करने का मतलब है कि आपको चीजों को बिट स्तर पर लिखना होगा, और यह मशीन की गति और निर्देशों के साथ थोड़ा नरक भी खेलता है क्योंकि सभी आधुनिक मशीनों में संरेखण होते हैं जो 8 बिट के गुणक होते हैं। उदाहरण के लिए, यही कारण है कि यूनिकोड UTF-8, UTF-16 और UTF-32 है।

यदि आप सुरक्षा के लिए ऐसा कर रहे हैं (इसीलिए आपने इसे Security.SE, right?) पर पोस्ट किया है, तो बस चीजों को फ़िल्टर करें और उन्हें सामान्य रूप से स्टोर करें। यदि आप अंतरिक्ष को बचाने के लिए ऐसा कर रहे हैं, तो विचार करें कि क्या सभी अतिरिक्त कोड और धीमी पहुंच समय (क्योंकि अधिकांश प्रविष्टियां पता सीमाओं को पार कर जाएंगी) अंतरिक्ष की बचत के लायक है।

द्वारा, निम्नलिखित एक सीएस कोर्स से स्निपेट है जहां हमें 8 बिट स्टोरेज से एएससीआईआई को 7 बिट में बदलना था:

    memset(dest,0x00,8);
    memcpy(dest, source, length);

    for (int i = 0; i < 8; i++) {
            if (dest[i] & 0x80) {
                    fprintf(stderr, "%s: %s\n", dest, "Illegal byte sequence");
                    exit(EILSEQ);
            }
    }

    dest[0] = 0x7F & dest[0] | 0x80 & dest[1] << 7;
    dest[1] = 0x3F & dest[1] >> 1 | 0xC0 & dest[2] << 6;
    dest[2] = 0x1F & dest[2] >> 2 | 0xE0 & dest[3] << 5;
    dest[3] = 0x0F & dest[3] >> 3 | 0xF0 & dest[4] << 4;
    dest[4] = 0x07 & dest[4] >> 4 | 0xF8 & dest[5] << 3;
    dest[5] = 0x03 & dest[5] >> 5 | 0xFC & dest[6] << 2;
    dest[6] = 0x01 & dest[6] >> 6 | 0xFE & dest[7] << 1;
    dest[7] = 0x00; //Clearing out

2

आप उदाहरण के लिए gzip, bzip2 या lzma के साथ डेटा को संपीड़ित कर सकते हैं और फिर उपयोग किए गए वर्ण सेट को सीमित करने के लिए बेस 64 के माध्यम से चला सकते हैं। यह केवल सैकड़ों बाइट्स या उससे अधिक के बड़े स्ट्रिंग्स पर फायदेमंद है।


1

क्यों नहीं LZ संपीड़न का उपयोग करें? यह एक स्ट्रिंग को संपीड़ित करने का एक सभ्य तरीका हो सकता है, लेकिन लंबे तारों के मामले में अधिक कुशल होगा। लक्ष्य स्ट्रिंग को आप कितने समय तक एन्कोड करना चाहते हैं?


अटारी सुझाव में उल्लेखित LZ संपीड़न की gzip या bzip2 से तुलना कैसे होती है?
NoChance 19

gzip LZ और Huffman Coding पर बनाया गया है। LZ en.wikipedia.org/wiki/LZ77 पर
A. राशद
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.