JVM संस्करण का पता लगाने के लिए एक जावा कोड लिखें


17

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

उस उद्देश्य को सुनिश्चित करने के लिए, सटीक औपचारिक नियम हैं:

  1. कोड जावा में लिखा होना चाहिए और जेआरई संस्करण को आउटपुट करना चाहिए जिसमें यह चल रहा है।

  2. कोड को विशेष रूप से जावा संस्करण का पता लगाने के लिए दिए गए किसी भी JDK या JRE API का उपयोग नहीं करना चाहिए या जो JDK या JRE संस्करण को मुफ्त में देता है।

  3. कोड प्रतिबिंब का उपयोग नहीं करना चाहिए।

  4. कोड केवल हॉटस्पॉट जावा एसई 5, 6 और 7 में काम करने के लिए आवश्यक है, लेकिन अन्य जेवीएम में काम कर सकता है।

  5. कोड को क्लासपाथ में किसी भी तीसरे पक्ष के पुस्तकालयों का उपयोग नहीं करना चाहिए।

  6. कोड को किसी अन्य प्रक्रिया, जावा या नहीं शुरू नहीं करना चाहिए।

  7. कोड को पर्यावरण चर का उपयोग नहीं करना चाहिए।

  8. कोड को पहले से मौजूद फ़ाइलों या फ़ोल्डरों की तलाश में फाइल सिस्टम की खोज नहीं करनी चाहिए।

  9. कोड एक एकल फाइल में निहित किया जाना चाहिए और के माध्यम से कहा जा public static void main(String[] args)या public static void main(String... args)

  10. कोड को JRE में मौजूद किसी भी गैर-सार्वजनिक API का उपयोग नहीं करना चाहिए।

  11. इसके निष्पादन के दौरान कोड को कोई NoClassDefFoundError, NoSuchMethodError, ClassNotFoundException या NoSuchMethodException उत्पन्न नहीं करना चाहिए।

  12. कोड को इंटरनेट या किसी स्थानीय नेटवर्क से डिस्कनेक्ट किए गए सिस्टम में चलना चाहिए।

  13. आपको एक स्पष्टीकरण देना चाहिए कि यह एक संस्करण में एक तरीके से और दूसरे संस्करण में दूसरे तरीके से क्यों व्यवहार करता है।

स्कोरिंग

सबसे अच्छा समाधान मापने के लिए उपयोग की जाने वाली विधि अधिकतम (n / s) है, जहां n इनमें से किसी भी नियम (कम से कम 5, 6 और 7) का उल्लंघन किए बिना विभिन्न जावा संस्करणों की संख्या का पता लगाया गया है और एस लेक्सिकल टोकन की संख्या है समाधान में।


एक बेहतर टैग नहीं मिल सका, और मुझे अंतिम दो में प्रदान करना था। इसके अलावा, नए टैग बनाने के लिए मेरे पास पर्याप्त प्रतिनिधि नहीं है। जावा का कारण यह है कि यह एक बहुत ही पोर्टेबल भाषा है, इसलिए यह लिखना बहुत दिलचस्प होगा। इसके अलावा, जावा संस्करणों को इस तरह से परिभाषित किया जाता है कि हम पर्यावरण की एकरूपता के साथ पता लगाने वाली प्रविष्टियों की तुलना कर सकते हैं, बिना सेब के संतरे की तुलना करना।
विक्टर स्टैफुसा

आप इस पर विचार कर सकते हैं कि वीएम संस्करण का पता लगाना प्रणाली पर हमला करने का एक कदम है। मैं यह नहीं कह सकता कि मेरे पास एक और सुझाव है।
dmckee --- पूर्व-मध्यस्थ ने बिल्ली का बच्चा

@dmckee ने [कोड-गोल्फ] टैग हटा दिया। [अंडरहैंड] टैग जोड़ें। क्या आप कृपया [जावा] टैग बना सकते हैं?
विक्टर स्टाफ़ुसा

4
मैं इस प्रश्न को ऑफ-टॉपिक के रूप में बंद करने के लिए मतदान कर रहा हूं क्योंकि इस साइट पर अंडरहैंड चुनौतियां अब ऑन-टॉपिक नहीं हैं। meta.codegolf.stackexchange.com/a/8326/20469
बिल्ली

@cat, आपको इसके बजाय टैग को हटा देना चाहिए था, क्योंकि यह प्रश्न फिट नहीं था।
पीटर टेलर

जवाबों:


9

6/102 = 0.0588

6 संस्करणों का पता लगाता है। (, के बाद मैं नष्ट कर दिया 103 से नीचे 102 शाब्दिक टोकन है publicमें public class)।

import java.security.Signature;

class GuessVersion {
        public static void main(String[] args) {
                String version = "Java 1.1";
                try {
                        "".getBytes("ISO8859_13");
                        version = "Java 1.3";

                        "".getBytes("ISO8859_15");
                        version = "Java 1.4";

                        Signature.getInstance("SHA256withRSA");
                        version = "Java 5";

                        "".getBytes("KOI8_U");
                        version = "Java 6";

                        Signature.getInstance("SHA256withECDSA");
                        version = "Java 7";
                } catch(Exception e) {}
                System.out.println(version);
        }
}

जावा 1.1 ने चरित्र एनकोडिंग और क्रिप्टोग्राफिक एल्गोरिदम को जावा में पेश किया। बाद के संस्करणों में अधिक एन्कोडिंग और एल्गोरिदम जोड़े गए। यह कार्यक्रम एन्कोडिंग और एल्गोरिदम का उपयोग करने की कोशिश करता है जब तक कि यह एक अपवाद को पकड़ता है। मैं फेंकने के लिए एक लापता एन्कोडिंग और फेंकने के लिए java.io.UnsupportedEncodingExceptionएक लापता एल्गोरिथ्म की उम्मीद करता हूं java.security.NoSuchAlgorithmException

मेरे पास जावा के चार पुराने संस्करणों के साथ एक पुराना पावरपीसी मैकिंटोश था। मेरी OpenBSD मशीन के दो और संस्करण हैं, इसलिए मैंने इन छह संस्करणों का परीक्षण किया:

  • मैक ओएस 9.2.2 के लिए एमआरजे 2.2.6 में जावा 1.1.8
  • मैक ओएस एक्स पैंथर के लिए जावा 1.3.1_16
  • मैक ओएस एक्स टाइगर के लिए जावा 1.4.2_21
  • मैक ओएस एक्स टाइगर के लिए जावा 1.5.0_19
  • OpenJDK 1.6.0_32 OpenBSD 5.5 के लिए
  • OpenJDK 1.7.0_21 OpenBSD 5.5 के लिए

यह प्रोग्राम OpenVD के लिए JamVM 1.5.4 और gcj 4.8.2 में भी चल सकता है, लेकिन अलग-अलग कार्यान्वयन के रूप में उनकी पहचान नहीं करता है। यह केवल "जावा 5" प्रिंट करता है।

जावा के लिए मैक ओएस रनटाइम

"एक बार लिखें, हर जगह दौड़ें!" के लिए धन्यवाद, मैं इस कार्यक्रम को एक बार लिख सकता हूं, इसे एक बार संकलित कर सकता हूं, और सभी आठ आभासी मशीनों में एक GuessVersion.class चला सकता हूं। मुझे अपने संग्रह में सबसे पुराना संस्करण जावा 1.1 के लिए एक कंपाइलर की आवश्यकता है।

मेरा संकलक javacएमआरजे एसडीके 2.2 से उपकरण है। क्‍योंकि क्‍लासिक मैक ओएस में कोई कमांड लाइन नहीं थी, javacएक बहुत ही ग्राफिकल टूल है, जहां मैं फाइलों और विकल्‍पों का चयन करता हूं और "डू जेवाक" पर क्लिक करता हूं। अपना कोड संपादित करने के बाद, मैं बस "Do Javac" पर फिर से क्लिक करता हूं।

क्लासिक मैक ओएस के लिए एमआरजे एसडीके 2.2 से जेवैक

GuessVersion.class को चलाने का सबसे आसान तरीका है, इसे JBindery में खोलना, MRJ SDK 2.2 का एक और टूल। रनटाइम एमआरजे 2.2.6, जावा 1.1.8 का कार्यान्वयन है।


22

मुझे यकीन नहीं है कि मेरा स्कोर क्या है, क्योंकि यह इस बात पर निर्भर करता है कि आप वास्तव में क्या एक शाब्दिक टोकन मानते हैं, लेकिन मैं उस गिनती प्रणाली का दुरुपयोग करने की कोशिश कर रहा हूं, जहां एक लंबी स्ट्रिंग के साथ जितना संभव हो सके ...

यह इस बात पर भी निर्भर करता है कि आप इसे 7 अलग-अलग संस्करणों या 16 के रूप में पहचानते हैं या नहीं ... (यह तुच्छ रूप से 190 तक बढ़ाया जा सकता है)।

class V extends ClassLoader
{
    public static void main(String[]args)
    {
        for(byte b=60;;)
            try {
                byte[]buf="\u00ca\u00fe\u00ba\u00be\u0000\u0000\u00002\u0000\u0005\u0007\u0000\u0003\u0007\u0000\u0004\u0001\u0000\u0001A\u0001\u0000\u0010java/lang/Object\u0006\u0000\u0000\u0001\u0000\u0002\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000".getBytes("ISO-8859-1");
                buf[7]=b--;
                new V().defineClass(buf,0,53);
                System.out.println(b-43);
                break;
            }
            catch(Throwable t){}
    }
}

यह क्लास प्रारूप के प्रमुख संस्करण संख्याओं के साथ एक कस्टम क्लास लोडर में एक इंटरफ़ेस को परिभाषित करने का प्रयास करता है। पहला जो java.lang.UnsupportedClassVersionErrorVM के संस्करण से मेल नहीं खाता है।


84 टोकन गिने गए। फिर भी इसका परीक्षण नहीं किया।
विक्टर स्टैफ़ुसा

आपका उत्तर जीनियल है। का उपयोग करके 83 टोकन तक कम कर सकते हैं String... args
विक्टर स्टाफ़ुसा

@ विक्टर, इस सवाल को उलझाएगा कि क्या यह 7 अलग-अलग संस्करणों को और अधिक समर्थन करता है। मैं किसी भी कंपाइलर के बारे में नहीं जानता जो जावा 5 सिंटैक्स का समर्थन करता है और जावा 1-संगत क्लास फ़ाइलों का संकलन करता है।
पीटर टेलर

अच्छी बात। मैं उसके बारे में भूल गया।
विक्टर स्टैफुसा

1
जावा 1.1.8 (एमआरजे 2.2.6 में) यह संकलन करने में विफल रहा, जब तक कि मैंने 17 और टोकन नहीं जोड़े protected Class loadClass(String name, boolean resolve) { return Object.class; }:। वर्तमान एपीआई डॉक्स का उल्लेख करने के लिए उपेक्षा करता है कि यह जावा 1.2 से पहले कैसे अमूर्त पद्धति थी। मैं Object.class वापस करता हूं क्योंकि विधि को "java.lang.Object" के लिए एक कॉल मिलती है।
kernigh

8
class Evil {
    public static void main(String... args) {
        String s1 = "Good";
        s1 += "morning";
        int a = 7;
        if (s1 != s1.intern())
            try {
                a--;
                javax.xml.datatype.DatatypeFactory.newInstance().newXMLGregorianCalendar().equals(null);
            } catch (Throwable e) {
                a--;
            }
        System.out.println(a);
    }
}

जावा 6 और 7 के बीच इंटर्निंग एल्गोरिदम बदल गया। /programming//a/7224864/540552 देखें

XMLGregorianCalendar.equals (नल) जावा 5 में NullPointerException को फेंकने के लिए उपयोग किया जाता है, लेकिन यह जावा 6 में तय किया गया था। http://bugs.sun.com/view_bug.do?bug_id/6285370 देखें

यहां पर 100 96 92 87 85 टोकन। 7 टोकन कम करने के लिए पीटर टेलर का धन्यवाद।


1
आप s1 में संस्करण संख्या को संग्रहीत करके 3 टोकन बचा सकते हैं। आप शायद एक और 2 को फेंकने योग्य को सीधे पकड़कर बचा सकते हैं, इस धारणा पर कि DatatypeConfigurationExceptionफेंक नहीं दिया जाएगा।
पीटर टेलर

1
या बेहतर है, int aलेकिन इसे तुरंत इनिशियलाइज़ करें, ताकि ifब्लॉक खाली हो जाए। शर्त को हटा दें, दूसरे को हटा दें, और --सीधे असाइनमेंट के बजाय उपयोग करें a
पीटर टेलर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.