यूनिकोड यूटीएफ कनवर्टर


17

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

विशेष विवरण

अगर किसी भी समय आपकी पसंद की भाषा किसी आवश्यकता को पूरा नहीं कर सकती है, तो उसे किसी ऐसी चीज से प्रतिस्थापित करें जो दिए गए नियमों की भावना को चुरा लेती है। उदाहरण के लिए। हर भाषा में अंतर्निहित सरणियाँ, कार्य आदि नहीं होते हैं।

  • स्ट्रिंग लाइब्रेरी / फ़ंक्शंस, या लाइब्रेरीज़ / फ़ंक्शंस का उपयोग न करना। इस कोड गोल्फ का बिंदु बिट / बाइट हेरफेर का उपयोग करके कनवर्टर को लागू करना है। हालांकि एक चरित्र या बाइट सरणी के रूप में अपनी क्षमता में स्ट्रिंग्स का उपयोग करने की अनुमति है। ओह, और कोई OS कॉल नहीं है जो या तो रूपांतरण करते हैं।

  • कनवर्टर एक फ़ंक्शन है जो तीन मापदंडों को ले जाएगा: एक बाइट सरणी एन्कोडेड इनपुट स्ट्रिंग का प्रतिनिधित्व करता है, और "इनपुट" और "आउटपुट" एन्कोडिंग को संख्याओं के रूप में दर्शाया गया है। UTF-8, UTF-16, UTF-16BE, UTF-16LE, UTF-32, UTF-32BE, and UTF32LEउस क्रम में हम 0 से 6 तक संख्या निर्दिष्ट करेंगे । यह जाँचने की कोई आवश्यकता नहीं है कि संख्या क्या है < 0या > 6, हम मान लेंगे कि ये पैरामीटर सही हैं। कनवर्टर वांछित आउटपुट एन्कोडिंग में एक मान्य बाइट सरणी लौटाएगा।

  • हम U+0000एक स्ट्रिंग टर्मिनेटर के रूप में अशक्त चरित्र ( ) का उपयोग करेंगे। इसके बाद कुछ भी मायने नहीं रखता। हम मानेंगे कि इनपुट ऐरे में अशक्त वर्ण कहीं है, इसलिए आपको सीमा जाँच करने की आवश्यकता नहीं है।

  • एफएक्यू के अनुसार , यदि इनपुट बाइट सरणी इसकी घोषित एन्कोडिंग के लिए अमान्य है, तो हमें एक त्रुटि का संकेत देना चाहिए। हम इसे निम्न तरीकों में से एक में करेंगे: प्रोग्राम को क्रैश करें, एक अपवाद फेंकें, अशक्त लौटें या एक सरणी वापस करें जिनके पहले चार बाइट्स सभी 0 हैं (ताकि इसे U+0000हर एन्कोडिंग के रूप में पहचाना जा सके )।

एनकोडिंग

आधिकारिक विनिर्देशों का पालन किया जाना चाहिए, लेकिन विकिपीडिया एन्कोडिंग के स्पष्टीकरण को एक अच्छा (और जहाँ तक मैं सही मानता हूँ) प्रदान करता है, और मैं उन्हें पूर्णता के लिए यहाँ संक्षेप में प्रस्तुत करूँगा। ध्यान दें कि UTF-16 और UTF-32 में एंडियनस के लिए वेरिएंट हैं ।

UTF-32, UTF-32LE, UTF-32BE

सबसे सरल एन्कोडिंग, प्रत्येक कोड बिंदु को इसके संख्यात्मक मान के बराबर 4 बाइट्स में एन्कोड किया गया है। LE / BE एंडियननेस (थोड़ा एंडियन / बड़ा एंडियन) का प्रतिनिधित्व करता है।

UTF-16, UTF-16LE, UTF-16BE

कोड अंक U+0000 - U+FFFFइसके बाइट में संख्यात्मक मान के बराबर 2 बाइट्स में एन्कोड किए गए हैं। सरोगेट्स की एक जोड़ी का उपयोग करके बड़े मानों को एन्कोड किया जाता है जो आरक्षित मान हैं U+D800 - U+DFFF। तो अंक से अधिक सांकेतिक शब्दों में बदलना करने के लिए U+FFFF, निम्नलिखित एल्गोरिथ्म का इस्तेमाल किया जा सकता है (बेशर्मी से विकिपीडिया से कॉपी ):

  • 0x010000 कोड बिंदु से घटाया जाता है, 0. बिट x0FFFFF में 20 बिट संख्या छोड़कर।
  • प्रथम कोड यूनिट या लीड सरोगेट देने के लिए शीर्ष दस बिट्स (रेंज 0..0x03FF में एक नंबर) को 0xD800 में जोड़ा जाता है, जो 0xD800..0xDBFF [...] रेंज में होगा।
  • दूसरी कोड यूनिट या ट्रेल सरोगेट देने के लिए कम दस बिट्स (सीमा 0..0x03FF में भी) 0xDC00 में जोड़े जाते हैं, जो कि 0xDC00..0xDFFF [...] रेंज में होगा।

UTF-8

कोड अंक U+0000 - U+007F1 बाइट के रूप में इसके सांख्यिक मूल्य के बराबर एन्कोडेड हैं। इनसे U+0080 - U+07FFएन्कोड किया जाता है 110xxxxx 10xxxxxx, जैसे U+0800 - U+FFFFकि 1110xxxx 10xxxxxx 10xxxxxx, उच्च मूल्य हैं 11110xxx 10xxxxxx 10xxxxxx 10xxxxxxxके कोड बिंदु के संख्यात्मक मान से बिट्स हैं।

बीओएम

बाइट-ऑर्डर मार्क (BOM U+FEFF) का उपयोग एंडियननेस को इंगित करने के लिए पहले कोड बिंदु के रूप में किया जाता है। बीओएम पर अक्सर पूछे जाने वाले प्रश्नों के दिशानिर्देशों के बाद , बीओएम का उपयोग निम्नानुसार किया जाएगा: क्योंकि UTF-8, UTF-16 and UTF-32यह वैकल्पिक है। यदि बीओएम अनुपस्थित है UTF-16या UTF-32, इसे बड़ा एंडियन माना जाता है। BOM में दिखाई नहीं देना चाहिएUTF-16LE, UTF-16BE, UTF-32LE and UTF-32BE

आम ख़राबियाँ अमान्य UTF के कारण

विभिन्न चीजें यूटीएफ को अमान्य करने के लिए बाइट अनुक्रम का कारण बन सकती हैं।

  • UTF-8 और UTF-32: सीधे सरोगेट कोड पॉइंट ( U+D800 - U+DFFF), या कोड पॉइंट को अधिक से अधिक एनकोडिंग U+10FFFF
  • UTF-8: कई अमान्य बाइट अनुक्रम।
  • UTF-16: अनुचित, या अनुचित तरीके से जोड़े गए सरोगेट।
  • BOM: एन्कोडिंग अनुभाग में निर्दिष्ट के रूप में इस्तेमाल किया जाना चाहिए। ध्यान दें कि आउटपुट करते समय UTF-16या UTF-32(कोई अंतर्निहित अंतःकरण निर्दिष्ट नहीं) आप चुन सकते हैं, लेकिन थोड़ा एंडियन के साथ, आपको बीओएम को शामिल करना होगा

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


"स्ट्रिंग लाइब्रेरी / फ़ंक्शंस या एन्कोडिंग लाइब्रेरीज़ / फ़ंक्शंस का उपयोग न करना।" वास्तविक बिल्ट-इन के बारे में क्या। एपीएल में, ''⎕R''⍠'InEnc' 'UTF16BE' 'OutEnc' 'UTF8-BOM'
Adám

2
@ एनबीजेड को इस चुनौती के बिंदु के बाद से उन व्यवहार को लागू करने की अनुमति नहीं दी जाएगी जो वे प्रदान करते हैं।
DPenner1

उत्तर देने वालों पर ध्यान दें: मैंने इस प्रश्न को कम या ज्यादा छोड़ दिया था, लेकिन हाल ही में नए सिरे से दिए गए ब्याज को देखते हुए, आने वाले दिनों में मुझे उत्तर देने में कुछ समय लगेगा।
DPenner1

जवाबों:


3

C ++, (UTF-8) 971 बाइट्स

#include<cstdint>
using u=uint8_t;using U=uint32_t;U i,o,x,b,m;U R(u*&p){x=*p++;if(!i){m=0;while(128>>m&x)++m;if(m>1)for(x&=127>>m;--m;)x=x<<6|((*p&192)-128?~0:*p++&63);return m?x=~0:x;}else if(i<3){x<<=8;x+=*p++;}else if(i<4){x+=*p++<<8;}else if(i<6){x<<=24;x+=*p++<<16;x+=*p++<<8;x+=*p++;}else{x+=*p++<<8;x+=*p++<<16;x+=*p++<<24;}return x;}U r(u*&p){U x0=R(p);if(i&&i<4&&x>>10==54)x=R(p)>>10==55?(x0<<10)+x-56613888:~0;if(!b++){if(x==65279)if(!i||i%3==1)r(p);else x=~0;else if(x==65534&&i==1)i=3,r(p);else if(x==4294836224&&i==4)i=6,r(p);}return x>1114111||x>>11==27?x=~0:x;}void w(U x,u*&p){if(!o){if(x<128)*p++=x;else{for(m=0;~63<<m&x;m+=6);for(*p++=~127>>m/6|x>>m;m;)*p++=128|x>>(m-=6)&63;}}else if(o<4&&x>65535)x-=65536,w(55296|x>>10,p),w(56320|x&1023,p);else if(o<3)*p++=x>>8,*p++=x;else if(o<4)*p++=x,*p++=x>>8;else if(o<6)*p++=x>>24,*p++=x>>16,*p++=x>>8,*p++=x;else*p++=x,*p++=x>>8,*p++=x>>16,*p++=x>>24;}int t(u*&p,u*&q){for(b=0,x=1;U(x+x);)w(r(p),q);return x;}

नीचे दिए गए पठनीय प्रोग्राम को निम्न पर्ल कमांड के माध्यम से फ़िल्टर करके उपरोक्त रूप में संघनित किया जा सकता है:

perl -p0 -e 's!//.*!!g;s/\s+/ /g;s/ \B|\B //g;s/0x[\da-f]+/hex($&)/ige;s/#include<[^<>]+>/\n$&\n/g;s/^\n+//mg'

उक्त आज्ञा

  • टिप्पणियाँ निकालता है
  • अनावश्यक व्हाट्सएप को हटाता है
  • षोडश आधारी को दशमलव में परिवर्तित करता है
  • #includeलाइनों के आसपास नए सिरे से बहाल करता है

पठनीय कोड

#include <cstdint>
using u = uint8_t;
using U = uint32_t;

U   i,                          // input encoding
    o,                          // output encoding
    x,                          // last read value
    b,                          // char count(BOM only valid when b==0)
    m;                          // temporary variable for measuring UTF-8

//   Encodings:
// 0 UTF-8
// 1 UTF-16
// 2 UTF-16BE
// 3 UTF-16LE
// 4 UTF-32
// 5 UTF-32BE
// 6 UTF-32LE

// Read a character or UTF-16 surrogate
U R(u*& p) {
    x = *p++;
    if (!i) { // UTF-8
        m=0; while (128>>m&x) ++m; // how many bytes?
        if (m>1) for (x&=127>>m; --m; ) x = x<<6 | ((*p&192)-128?~0:*p++&63);
        return m ? x=~0 : x;
    } else if (i<3) { // UTF-16, UTF-16BE
        x<<=8; x+=*p++;
    } else if (i<4) { // UTF-16LE
        x+=*p++<<8;
    } else if (i<6) { // UTF-32, UTF-32BE
        x<<=24; x+=*p++<<16; x+=*p++<<8; x+=*p++;
    } else { // UTF-32LE
        x+=*p++<<8; x+=*p++<<16; x+=*p++<<24;
    }
    return x;
}

// Read a character, combining surrogates, processing BOM, and checking range
U r(u*& p) {
    U x0 = R(p);
    if (i && i<4 && x>>10==54)
        x = R(p)>>10==55 ? (x0<<10)+x-56613888: ~0; // 56613888 == 0xd800<<10 + 0xdc00 - 0x10000
    if (!b++) {                 // first char - is it BOM?
        if (x==0xFEFF)
            if (!i || i%3==1)
                r(p); // BOM in UTF-8 or UTF-16 or UTF-32 - ignore, and read next char
            else
                x = ~0; // not allowed in these modes
        else if (x==0xFFFE && i==1)
            i=3,r(p); // reversed BOM in UTF-16 - change to little-endian, and read next char
        else if (x==0xFFFE0000 && i==4)
            i=6,r(p); // reversed BOM in UTF-32 - change to little-endian, and read next char
    }
    return x>0x10ffff || x>>11==27 ? x=~0 : x;
}


// Write character(assumed in-range)
void w(U x, u*& p) {
    if (!o) { // UTF-8
        if (x<128) *p++=x;        // ASCII
        else {
            for (m=0; ~63<<m&x; m+=6); // how many bits?
            for (*p++=~127>>m/6|x>>m; m; ) *p++ = 128|x>>(m-=6)&63;
        }
    } else if (o<4 && x>65535)  // UTF-16 surrogate
        x-=65536, w(0xD800|x>>10,p), w(0xDC00|x&0x3FF,p);
    else if (o<3)  // UTF-16, UTF-16BE
        *p++=x>>8, *p++=x;
    else if (o<4)  // UTF-16LE
        *p++=x, *p++=x>>8;
    else if (o<6)  // UTF-32, UTF-32BE
        *p++=x>>24, *p++=x>>16, *p++=x>>8, *p++=x;
    else  // UTF-32LE
        *p++=x, *p++=x>>8, *p++=x>>16, *p++=x>>24;
}

// Transcode
int t(u*& p, u*& q)                  // input, output
{
    for (b=0,x=1;U(x+x);)    // exit condition is true only for x==-x, i.e. 0 and ~0
        w(r(p),q);
    return x;
}

कहा जाने वाला कार्य t(), वैश्विक चर iऔर oक्रमशः इनपुट और आउटपुट एन्कोडिंग के साथ है , और इनपुट pके बाइट्स पर इंगित करता है, जिसे शून्य-समाप्त होना चाहिए। qआउटपुट बफर को इंगित करता है, जिसे ओवरराइट किया जाएगा, और परिणाम के लिए पर्याप्त बड़ा होना चाहिए - बफर ओवररन से बचने का कोई प्रयास नहीं है।

मुझे उम्मीद है कि कोड टिप्पणियां पर्याप्त रूप से व्याख्यात्मक हैं - नीचे से पूछें कि क्या उनमें से एक भी गूढ़ है (लेकिन पहले प्रयास करें!)।

मैंने इस उत्तर को विकसित करते हुए एक पर्याप्त परीक्षण सूट संकलित किया; मैं इसे अन्य प्रवेशकों के लाभ के लिए, और आवश्यकताओं की मेरी व्याख्या का दस्तावेजीकरण करने के लिए नीचे शामिल करता हूं:

परीक्षण कार्य

#include <vector>
#include <iostream>

std::ostream& operator<<(std::ostream& out, const std::vector<u>& v)
{
    out << "{ ";
    for (int i: v) out << i << " ";
    out << "}";
    return out;
}

int test_read(int encoding, std::vector<u> input, U expected)
{
    b = 0;
    i = encoding;
    auto d = input.data();
    U actual = r(d);
    if (actual == expected) return 0;
    std::cerr << std::hex << "Decoding " << encoding << "; " << input << " gave " << actual
              << " instead of " << expected << std::endl;
    return 1;
}

int test_write(int encoding, U input, std::vector<u> expected)
{
    o = encoding;
    u buf[20], *p = buf;
    w(input, p);
    std::vector<u> actual(buf,p);
    if (expected == actual) return 0;
    std::cerr << std::hex << "Encoding " << encoding << "; " << input << " gave " << actual
              << " instead of " << expected << std::endl;
    return 1;
}

int test_transcode(int ienc, std::vector<u> input, int oenc, std::vector<u> expected)
{
    b = 0;
    i = ienc; o = oenc;
    u buf[200], *p = buf, *d = input.data();
    int result = t(d, p);
    std::vector<u> actual(buf,p);
    if (result ? expected.empty() : expected == actual) return 0;
    std::cerr << std::hex << "Encoding " << ienc << " to " << oenc << "; " << input << " gave " << actual
              << " instead of " << expected << std::endl;
    return 1;
}

परीक्षण सूट

static const U FAIL = ~0;
int main() {
    int e = 0;                        // error count
    // UTF-8
    e += test_read(0, { 128 }, FAIL); // unexpected continuation
    e += test_read(0, { 128, 1 }, FAIL);
    e += test_read(0, { 128, 128 }, FAIL);
    e += test_read(0, { 192, 192 }, FAIL); // start without continuation
    e += test_read(0, { 192, 0 }, FAIL);
    e += test_read(0, { 224, 0 }, FAIL);
    e += test_read(0, { 224, 192 }, FAIL);
    e += test_read(0, { 0xf4, 0x90, 128, 128 }, FAIL); // Unicode maximum+1

    e += test_read(0, { 127 }, 127);
    e += test_read(0, { 192, 129 }, 1); // We accept overlong UTF-8
    e += test_read(0, { 0xc2, 128 }, 128);
    e += test_read(0, { 224, 128, 129 }, 1);
    e += test_read(0, { 0xef, 128, 128 }, 0xF000);
    e += test_read(0, { 0xef, 191, 191 }, 0xFFFF);
    e += test_read(0, { 0xf4, 128, 128, 128 }, 0x100000);
    e += test_read(0, { 0xf4, 0x8f, 191, 191 }, 0x10FFFF); // Unicode maximum

    e += test_read(0, { 0xEF, 0xBB, 0xBF, 127 }, 127); // byte-order mark

    e += test_write(0, 0, { 0 });
    e += test_write(0, 127, { 127 });
    e += test_write(0, 128, { 0xc2, 128 });
    e += test_write(0, 255, { 0xc3, 191 });
    e += test_write(0, 0xFFFF, { 0xef, 191, 191 });
    e += test_write(0, 0x10FFFF, { 0xf4, 0x8f, 191, 191 });

    // UTF-16
    e += test_read(1, { 0, 1 }, 1);
    e += test_read(1, { 0xd8, 0, 0xdc, 1 }, 0x10001);
    e += test_read(1, { 0xdb, 0xff, 0xdf, 0xff }, 0x10ffff);

    e += test_read(1, { 0xd8, 0, 0xd8, 1 }, FAIL); // mismatched surrogate
    e += test_read(1, { 0xd8, 0, 0, 1 }, FAIL); // mismatched surrogate
    e += test_read(1, { 0xdc, 0 }, FAIL);

    e += test_write(1, 1, { 0, 1 });
    e += test_write(1, 256, { 1, 0 });
    e += test_write(1, 0xffff, { 255, 255 });
    e += test_write(1, 0x10001, { 0xd8, 0, 0xdc, 1 });
    e += test_write(1, 0x10ffff, { 0xdb, 0xff, 0xdf, 0xff });

    // UTF-16LE
    e += test_write(3, 1, { 1, 0 });
    e += test_write(3, 256, { 0, 1 });
    e += test_write(3, 0x10001, { 0, 0xd8, 1, 0xdc });
    e += test_write(3, 0x10fffe, { 0xff, 0xdb, 0xfe, 0xdf });

    // UTF-16 byte-order mark
    e += test_read(1, { 0xFE, 0xFF, 0x0, 1 }, 1); // byte-order mark
    e += test_read(1, { 0xFF, 0xFE, 1, 0x0 }, 1); // reversed byte-order mark
    // disallowed byte-order marks
    e += test_read(2, { 0xFE, 0xFF }, FAIL);
    e += test_read(3, { 0xFF, 0xFE }, FAIL);
    // reversed byte-order mark is an unassigned character - to be treated like regular character, according to question
    e += test_read(2, { 0xFF, 0xFE }, 0xfffe);
    e += test_read(3, { 0xFE, 0xFF }, 0xfffe);

    // UTF-32
    e += test_read(4, { 0, 0, 0, 1 }, 1);
    e += test_read(4, { 1, 0, 0, 0 }, FAIL);
    e += test_write(4, 1, { 0, 0, 0, 1 });
    e += test_write(4, 0x10203, { 0, 1, 2, 3 });

    // UTF-32LE
    e += test_read(6, { 0, 0, 0, 1 }, FAIL);
    e += test_read(6, { 1, 0, 0, 0 }, 1);

    // UTF-32 byte-order mark
    e += test_read(4, { 0, 0, 0xFE, 0xFF,  0, 0, 0, 1 }, 1); // byte-order mark
    e += test_read(4, { 0xFF, 0xFE, 0, 0,  1, 0, 0, 0 }, 1); // reversed byte-order mark
    // disallowed byte-order marks
    e += test_read(5, { 0, 0, 0xFE, 0xFF }, FAIL);
    e += test_read(5, { 0xFF, 0xFE, 0, 0 }, FAIL);
    e += test_read(6, { 0, 0, 0xFE, 0xFF }, FAIL);
    e += test_read(6, { 0xFF, 0xFE, 0, 0 }, FAIL);

    e += test_transcode(1, { 1, 2, 0xFE, 0xFF, 0, 0 }, // That's not a BOM; it's a zwnj when not the first char
                        1, { 1, 2, 0xFE, 0xFF, 0, 0 });
    e += test_transcode(1, { 0xFF, 0xFE, 1, 2, 0, 0 }, // reversed byte-order mark implies little-endian
                        1, { 2, 1, 0, 0 });
    e += test_transcode(4, { 0xFF, 0xFE, 0, 0, 1, 2, 0, 0, 0, 0 }, // reversed BOM means little-endian
                        4, { 0, 0, 2, 1, 0, 0, 0, 0 });
    e += test_transcode(1, { 0xdb, 0xff, 0xdf, 0xff, 0, 0 }, // U+10ffff UTF-16 to UTF-8
                        0, { 0xf4, 0x8f, 191, 191, 0 });

    return e;
}

डांग .. C ++ ने पायथन को हराया।
टिकटॉक

5

पायथन - 1367 यूटीएफ -8 चार्ट

ठीक है! यह एक बेहद कठिन सवाल था क्योंकि सभी विशिष्टताओं को समझने और लागू करने में काम की मात्रा के कारण, लेकिन मुझे लगता है कि मेरे पास एक सही कार्यान्वयन है।

O,P,Q,R=65536,128,b'\xff\xfe\x00\x00',63
def A(x,y):assert x;return y
def B(x):
    o,c=[],0
    for b in x:
        if c:c,v=c-1,A(127<b<192,v<<6)|(b-P)
        else:
            c,v=(b>127)+(b>223)+(b>239),b
            if b>127:v=A(191<b<248,b&(R>>c))
        o+=[v][c:]
    return o[o[0]in(65279,O-2):]
def C(k):
    def o(x,s=None):
        for a,b in zip(x[k::2],x[1-k::2]):
            d=a|(b<<8)
            if s!=None:yield(A(56319<d<57344,d-56320)|(s<<10))+O;s=None
            elif 55295<d<57344:s=A(s<1024,d-55296)
            else:yield d
    return o
def D(x):n=(2,3,1)[[Q[:2],Q[1::-1],x[:2]].index(x[:2])];return C(n&1)(x[n&2:])
E=lambda a,b,c,d:lambda x:[L|(l<<8)|(m<<16) for L,l,m in zip(x[a::4],x[b::4],x[c::4])]
def F(x):n,m=((1,4),(-1,4),(-1,0))[[Q,Q[::-1],x[:4]].index(x[:4])];return E(*range(4)[::n])(x[m:])
S=lambda x,s=0,a=255:(x>>s)&a
G=lambda e:(e,)if e<P else(192|S(e,6),P|(e&R))if e<2048 else(224|S(e,12),P|S(e,6,R),P|(e&R))if e<O else(240|S(e,18),P|S(e,12,R),P|S(e,6,R),P|(e&R))
H=lambda e:(S(e,8),S(e))if e<O else(216|S(e-O,18),S(e-O,10),220+S((e-O)&1023,8),S(e-O))
I=lambda e:(S(e),S(e,8))if e<O else(S(e-O,10),216|S(e-O,18),S(e-O),220+S((e-O)&1023,8))
J=lambda e:(S(e,24),S(e,16),S(e,8),S(e))
K=lambda e:(S(e),S(e,8),S(e,16),S(e,24))
convert=lambda d,i,o:bytes(sum(map(L[o],N(list(M[i](d)))),()))if d else d
L,M=[G,H,H,I,J,J,K],[B,D,C(1),C(0),F,E(3,2,1,0),E(0,1,2,3)]
N=lambda d:[A(-1<x<1114112 and x&~2047!=55296,x)for x in d]

convertवह फ़ंक्शन है जो डेटा 'बाइट्स' ऑब्जेक्ट, इनपुट आईडी और आउटपुट आईडी लेता है। यह काम करने के लिए लगता है - हालाँकि एन्कोडिंग में अनिर्दिष्ट होने पर अजगर को बीओएम का थोड़ा टूटा हुआ उपयोग होता है, इसलिए 1 और 4 परीक्षण मोड में अजगर के अंतर्निहित एन्कोडिंग का उपयोग करने से काम नहीं चलेगा।

मजेदार तथ्य: आकार भी 555 16 या 10101010101 2 है

डिकोडिंग के लिए 773 चार्ट, एन्कोडिंग के लिए 452, सत्यापन के लिए 59 और विविध भागों के लिए 83।


@TrangOul: आम तौर पर, तुच्छ संपादन (जैसे भाषा टैगिंग) पर फेंक दिया जाता है।
Zach गेट्स


यह प्रश्न / उत्तर सामुदायिक सहमति नहीं दिखाता है। नेटवर्क के पार, इन जैसे तुच्छ सम्पादन को पूरा किया जाता है। जब तक वे स्पष्ट रूप से सामग्री या प्रारूप में सुधार नहीं करते हैं, न तो <1000 और न ही> 1000 प्रतिनिधि उपयोगकर्ताओं को ये संपादन करने चाहिए। भाषा के टैग, एकल शब्द सुधार / परिवर्तन आदि जैसी चीजों को संपादित करना सबसे अच्छा है, @cat
Zach Gates

मुझे लगता है कि आकार अब 0x555 :-( नहीं है। लेकिन आप मानक पायथन-गोल्फ टिप का उपयोग करके इंडेंट के लिए एक स्थान का उपयोग कर करीब पहुंच सकते हैं।
टोबी स्पाइट

@TobySpeight यह अभी 0x557 है, आप सही हैं। और वास्तव में, मैंने टैब का उपयोग किया, जिसे पोस्ट करने के लिए रिक्त स्थान में परिवर्तित किया जाना था, लेकिन फिर भी एक चरित्र के रूप में गिना जाता है। मैं देखूंगा कि क्या मुझे मौका मिलने पर कुछ और पात्रों को शेव कर सकता हूं।
सेल स्केग्स

4

पायथन 3, 1138 बाइट्स (UTF-8)

तो यह पता चला है कि 14 घंटे की अंतरराष्ट्रीय यात्रा एक शानदार चुनौती को समाप्त करने का एक शानदार अवसर है ...

रूपांतरण समारोह है C()। यह कॉल करता है u(), v()और क्रमशः w()डीकोड, और U(), V()और W()एनकोड करने के लिए, UTF-8, -16 और -32, क्रमशः। एनकोडर में से कोई भी बीओएम का उत्पादन नहीं करेगा, लेकिन सभी डिकोडर सही ढंग से एक को संभाल लेंगे। त्रुटि स्थितियों के परिणामस्वरूप एक अपवाद होता है (आमतौर पर ZeroDivisionError"डाई-अचानक" फ़ंक्शन के सौजन्य से E())।

from struct import*
l=len
j=''.join
b=lambda c:[*bin(c)[2:]]
P,Q,i,o,z,Z='HI10><'
B=65279
O,F,H,L,X=1024,65536,55296,56320,57344
E=lambda:1/0
R=lambda y,e,c,n:unpack(([[z,Z][y[:n]==pack(Z+c,B)],e][l(e)])+c*(l(y)//n),y)
S=lambda d,e:B!=d[0]and d or e and E()or d[1:]
def u(y,d=(),p=0):
 while p<l(y):
  q=b(y[p])
  if l(q)>7:
   x=q.index(o);C=1<x<5and q[x+1:]or E();X=x+p;X>l(y)>E();p+=1
   while p<X:q=b(y[p]);C=l(q)>7and(i,o==q[:2])and(*C,*q[2:])or E();p+=1
   d=*d,int(j(C),2)
  else:d=*d,y[p];p+=1
 return S(d,0)
def T(p):
 q=b(p);C=()
 while l(q)not in(7,11,16,21):q=o,*q
 while l(q)>6:C=int(i+o+j(q[-6:]),2),*C;q=q[:-6]
 return bytes(p<128and[p]or[int(i*(7-l(q))+o+j(q),2),*C])
U=lambda c:b''.join(map(T,c))
def v(y,e=''):
 c=R(y,e,P,2);d=[];n=0
 while n<l(c)-1:h,a=c[n:n+2];D=[(h,a),(F+(h-H)*O+a-L,)][H<=h<L<=a<X];M=3-l(D);n+=M;d+=D[:M]
 if n<l(c):d=*d,c[n]
 return S(d,e)
V=lambda c,e=z:W(sum(map(lambda p:([H+(p-F)//O,L+(p-F)%O],[p])[p<F],c),[]),e,P)
w=lambda y,e='':S(R(y,e,Q,4),e)
W=lambda c,e=z,C=Q:pack(e+C*l(c),*c)
K=(u,U),(v,V),(v,V,z),(v,V,Z),(w,W),(w,W,z),(w,W,Z)
def C(y,f,t):f,_,*a=K[f];_,t,*b=K[t];return t(f(y,*a),*b)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.