यह "हैलो वर्ल्ड" कैसे छापता है?


163

मैंने इस विचित्रता की खोज की:

for (long l = 4946144450195624l; l > 0; l >>= 5)
    System.out.print((char) (((l & 31 | 64) % 95) + 32));

आउटपुट:

hello world

यह कैसे काम करता है?


14
मेरा मतलब है कि आप इसका पता लगा सकते हैं।
सोतीरियोस डेलिमोलिस

30
हाँ। मैं मानता हूं ... मैं टोपी के लिए :) मछली पकड़ने कर रहा हूँ
बोहेमियन

6
मुझे लगता है कि मैंने इससे पहले पूछे गए इस सवाल को देखा है ..
Zavior

6
@ ओली उसके लिए एक टोपी होनी चाहिए।
सोतीरियोस डेलिमोलिसिस 15

12
इस तरह के प्रश्न, जो डेटाबेस में सुधार नहीं करते हैं, लेकिन केवल clickbait के रूप में मौजूद हैं, भविष्य में Hat गेम को रद्द करने का एक निश्चित तरीका है। कृपया इसके लिए व्हाट्सएप करके गेम को बर्बाद न करें।
ब्लेज़ेमॉन्गर

जवाबों:


256

संख्या 494614445019562464 बिट्स फिट होती है, इसका द्विआधारी प्रतिनिधित्व है:

 10001100100100111110111111110111101100011000010101000

कार्यक्रम हर 5-बिट समूह के लिए, दाएं से बाएं तक एक चरित्र को डिकोड करता है

 00100|01100|10010|01111|10111|11111|01111|01100|01100|00101|01000
   d  |  l  |  r  |  o  |  w  |     |  o  |  l  |  l  |  e  |  h

5-बिट कोडिनेशन

5 बिट्स के लिए, यह 2 bits = 32 वर्णों का प्रतिनिधित्व करने के लिए पॉसिबल है। अंग्रेजी वर्णमाला में 26 अक्षर होते हैं, इस पत्र के अलावा 32 - 26 = 6 प्रतीकों के लिए कमरा छोड़ दिया जाता है। इस कोडीकरण योजना के साथ आपके पास सभी 26 (एक मामला) अंग्रेजी अक्षर और 6 प्रतीक (उनके बीच जगह हो सकती है) हो सकते हैं।

एल्गोरिथम विवरण

इन >>= 5-लूप समूह से समूह में कूदता है, फिर 5-बिट समूह अलग-थलग हो जाता 31₁₀ = 11111₂है और वाक्य में मास्क के साथ संख्या को अंजाम देता हैl & 31

अब कोड 5-बिट वैल्यू को उसके संबंधित 7-बिट एससीआई कैरेक्टर पर मैप करता है। यह मुश्किल हिस्सा है, निम्न तालिका में निचले अक्षर वर्णमाला के लिए द्विआधारी प्रतिनिधित्व की जाँच करें:

  ascii   |     ascii     |    ascii     |    algorithm
character | decimal value | binary value | 5-bit codification 
--------------------------------------------------------------
  space   |       32      |   0100000    |      11111
    a     |       97      |   1100001    |      00001
    b     |       98      |   1100010    |      00010
    c     |       99      |   1100011    |      00011
    d     |      100      |   1100100    |      00100
    e     |      101      |   1100101    |      00101
    f     |      102      |   1100110    |      00110
    g     |      103      |   1100111    |      00111
    h     |      104      |   1101000    |      01000
    i     |      105      |   1101001    |      01001
    j     |      106      |   1101010    |      01010
    k     |      107      |   1101011    |      01011
    l     |      108      |   1101100    |      01100
    m     |      109      |   1101101    |      01101
    n     |      110      |   1101110    |      01110
    o     |      111      |   1101111    |      01111
    p     |      112      |   1110000    |      10000
    q     |      113      |   1110001    |      10001
    r     |      114      |   1110010    |      10010
    s     |      115      |   1110011    |      10011
    t     |      116      |   1110100    |      10100
    u     |      117      |   1110101    |      10101
    v     |      118      |   1110110    |      10110
    w     |      119      |   1110111    |      10111
    x     |      120      |   1111000    |      11000
    y     |      121      |   1111001    |      11001
    z     |      122      |   1111010    |      11010

यहाँ आप देख सकते हैं कि हम जो अस्सुरी पात्र बनाना चाहते हैं वह and वें और ६ वें बिट सेट ( 11xxxxx₂) के साथ शुरू होता है (अंतरिक्ष को छोड़कर, जिस पर केवल ६ वाँ बिट है), आप OR५-बिट कॉर्डिफिकेशन के साथ 96( 96₁₀ = 1100000₂) और वह होना चाहिए मैपिंग करने के लिए पर्याप्त है, लेकिन यह अंतरिक्ष के लिए काम नहीं करेगा (darn space!)

अब हम जानते हैं कि अन्य पात्रों की तरह अंतरिक्ष में भी प्रक्रिया करने के लिए विशेष ध्यान रखना पड़ता है। इसे प्राप्त करने के लिए, कोड एक OR 64 64₁₀ = 1000000₂( l & 31 | 64) के साथ निकाले गए 5-बिट समूह पर 7 वें बिट (लेकिन 6 वें नहीं) को चालू करता है ।

अब तक 5-बिट समूह फॉर्म का है: 10xxxxx₂(स्पेस होगा 1011111₂ = 95₁₀)। यदि हम 0अन्य मूल्यों को अप्रभावित करने के लिए अंतरिक्ष का नक्शा बना सकते हैं, तो हम 6 बिट को चालू कर सकते हैं और यह सब होना चाहिए। यहाँ वह mod 95हिस्सा है जो खेलने के लिए आता है, स्पेस है 1011111₂ = 95₁₀, मॉड ऑपरेशन का उपयोग करके (l & 31 | 64) % 95)केवल स्पेस वापस चला जाता है 0और इसके बाद, कोड 32₁₀ = 100000₂ पिछले परिणाम में जोड़कर 6 बिट को चालू करता है , ((l & 31 | 64) % 95) + 32)5-बिट वैल्यू को एक वैध एससीआई में बदल देता है। चरित्र

isolates 5 bits --+          +---- takes 'space' (and only 'space') back to 0
                  |          |
                  v          v
               (l & 31 | 64) % 95) + 32
                       ^           ^ 
       turns the       |           |
      7th bit on ------+           +--- turns the 6th bit on

निम्न कोड उलटा प्रक्रिया करता है, जिसे एक लोअरकेस स्ट्रिंग (अधिकतम 12 चार्ट) दिया जाता है, 64 बिट लंबा मान देता है जिसका उपयोग ओपी कोड के साथ किया जा सकता है:

public class D {
    public static void main(String... args) {
        String v = "hello test";
        int len = Math.min(12, v.length());
        long res = 0L;
        for (int i = 0; i < len; i++) {
            long c = (long) v.charAt(i) & 31;
            res |= ((((31 - c) / 31) * 31) | c) << 5 * i;
        }
        System.out.println(res);
    }
}    

11
यह उत्तर कोई रहस्य नहीं छोड़ता। बल्कि, यह आपकी सोच को आपके लिए करता है।

7
इसका उत्तर प्रश्न से भी कठिन है: D
Yazan

1
स्पष्टीकरण बहुत क्लीनर है :)
प्रशांत

40

उपरोक्त उत्तरों में कुछ मूल्य जोड़ना। ग्रूवी स्क्रिप्ट के बाद मध्यवर्ती मूल्यों को प्रिंट करता है।

String getBits(long l) {
return Long.toBinaryString(l).padLeft(8,'0');
}

for (long l = 4946144450195624l; l > 0; l >>= 5){
    println ''
    print String.valueOf(l).toString().padLeft(16,'0')
    print '|'+ getBits((l & 31 ))
    print '|'+ getBits(((l & 31 | 64)))
    print '|'+ getBits(((l & 31 | 64)  % 95))
    print '|'+ getBits(((l & 31 | 64)  % 95 + 32))

    print '|';
    System.out.print((char) (((l & 31 | 64) % 95) + 32));
}

यह रहा

4946144450195624|00001000|01001000|01001000|01101000|h
0154567014068613|00000101|01000101|01000101|01100101|e
0004830219189644|00001100|01001100|01001100|01101100|l
0000150944349676|00001100|01001100|01001100|01101100|l
0000004717010927|00001111|01001111|01001111|01101111|o
0000000147406591|00011111|01011111|00000000|00100000| 
0000000004606455|00010111|01010111|01010111|01110111|w
0000000000143951|00001111|01001111|01001111|01101111|o
0000000000004498|00010010|01010010|01010010|01110010|r
0000000000000140|00001100|01001100|01001100|01101100|l
0000000000000004|00000100|01000100|01000100|01100100|d

26

दिलचस्प!

मानक ASCII वर्ण जो दिखाई दे रहे हैं वे 32 से 127 की सीमा में हैं।

इसीलिए आप वहां 32, और 95 (127 - 32) देखें।

वास्तव में प्रत्येक चरित्र को यहां 5 बिट्स पर मैप किया जाता है, (आप पा सकते हैं कि प्रत्येक वर्ण के लिए 5 बिट संयोजन क्या है), और फिर सभी बिट्स को बड़ी संख्या बनाने के लिए संक्षिप्त किया जाता है।

सकारात्मक लोंग 63 बिट संख्या होते हैं, जो कि 12 वर्णों के एन्क्रिप्टेड रूप को धारण करने के लिए पर्याप्त होते हैं। इसलिए यह धारण करने के लिए काफी बड़ा है Hello word, लेकिन बड़े ग्रंथों के लिए आप बड़ी संख्या, या यहां तक ​​कि एक बिगइन्टर का उपयोग करेंगे।


एक आवेदन में हम एसएमएस के माध्यम से दृश्य अंग्रेजी वर्ण, फारसी वर्ण और प्रतीकों को स्थानांतरित करना चाहते थे। जैसा कि आप देख रहे हैं32 (number of Persian chars) + 95 (number of English characters and standard visible symbols) = 127 संभावित मूल्य हैं, जिन्हें 7 बिट्स के साथ दर्शाया जा सकता है।

हमने प्रत्येक UTF-8 (16 बिट) वर्ण को 7 बिट्स में बदल दिया, और 56% से अधिक संपीड़न अनुपात प्राप्त किया। इसलिए हम एक ही संख्या के एसएमएस में दो बार लंबाई के साथ ग्रंथ भेज सकते हैं। (यह किसी तरह एक ही बात यहाँ है)।


ओपी के कोड में बहुत कुछ चल रहा है। उदाहरण के लिए, यह वास्तव में व्याख्या नहीं करता है कि क्या | 64कर रहा है।
टेड हॉप

1
@Amir: वास्तव में 95 है क्योंकि आपको एक अंतरिक्ष वर्ण प्राप्त करने की आवश्यकता है।
मधुमक्खी

17

आपको एक परिणाम मिल रहा है जो charनीचे के मूल्यों का प्रतिनिधित्व करता है

104 -> h
101 -> e
108 -> l
108 -> l
111 -> o
32  -> (space)
119 -> w
111 -> o
114 -> r
108 -> l
100 -> d

16

आपने 5-बिट मानों के रूप में वर्ण एन्कोड किए हैं और उनमें से 11 को 64 बिट लंबे में पैक किया है।

(packedValues >> 5*i) & 31 0-31 की रेंज के साथ i-th एनकोडेड वैल्यू है।

जैसा कि आप कहते हैं, कठिन हिस्सा, अंतरिक्ष को कूट रहा है। निचले मामले के अंग्रेजी अक्षरों में यूनिकोड (और एससीआई, और अधिकांश अन्य एनकोडिंग) में सन्निहित सीमा 97-122 है, लेकिन स्थान 32 है।

इसे दूर करने के लिए, आपने कुछ अंकगणित का उपयोग किया। ((x+64)%95)+32लगभग उसी तरह है x + 96(ध्यान दें कि बिटवाइस या इस मामले में इसके बराबर कैसे है), लेकिन जब x = 31 होता है, तो हम प्राप्त करते हैं 32


6

यह एक समान कारण के लिए "हैलो वर्ल्ड" प्रिंट करता है:

for (int k=1587463874; k>0; k>>=3)
     System.out.print((char) (100 + Math.pow(2,2*(((k&7^1)-1)>>3 + 1) + (k&7&3)) + 10*((k&7)>>2) + (((k&7)-7)>>3) + 1 - ((-(k&7^5)>>3) + 1)*80));

लेकिन इस से कुछ अलग कारण के लिए:

for (int k=2011378; k>0; k>>=2)
    System.out.print((char) (110 + Math.pow(2,2*(((k^1)-1)>>21 + 1) + (k&3)) - ((k&8192)/8192 + 7.9*(-(k^1964)>>21) - .1*(-((k&35)^35)>>21) + .3*(-((k&120)^120)>>21) + (-((k|7)^7)>>21) + 9.1)*10));

18
आपको यह स्पष्ट करना चाहिए कि आप क्या कर रहे हैं, एक और पहेली पोस्ट करने के बजाय
ins13 डबिन्सकी

1
मेरा सुझाव है कि आप एक साइट (शायद कुछ बीटा स्टेक्सएक्सचेंज?) खोजने में कुछ प्रयास करते हैं, जहां मजेदार पहेलियों का योगदान स्वागत योग्य है। स्टैक ओवरफ्लो एक क्यु एंड ए साइट है जिसमें कड़ाई से लागू किया गया है।
मार्को टोपोलनिक

1
@MarkoTopolnik मैं ऐसी दुनिया में रहना पसंद करूंगा जहां सभी नियम या फ़ोकस इतनी सख्ती से लागू किए गए थे कि कभी भी कोई अपवाद नहीं होने दिया। यह उल्लेख नहीं है कि एसओ पर अनगिनत ऐसे अपवाद हैं।
לעג ברקן

1
मैं भी, लेकिन एसओ एक ऐसी दुनिया है जो असामान्य रूप से बहुत हद तक है। निश्चित रूप से यहां भी अपवाद हैं, लेकिन उनका स्वागत नहीं है ।
मार्को टोपोलनिक

1
एक और 15 ने एलेक्जेंडर की भावना को साझा किया। और आप यह इंगित करने में सही हैं कि एसओ के लिए यह प्रश्न अपने आप में अनुपयुक्त है, जैसा कि नीचे टिप्पणी की गई है।
मार्को टोपोलनिक

3

बिना ए Oracle टैग के , इस प्रश्न को देखना मुश्किल था। सक्रिय इनाम मुझे यहाँ लाया। काश सवाल अन्य प्रासंगिक प्रौद्योगिकी टैग भी था :-(

मैं ज्यादातर साथ काम करता हूं Oracle database, इसलिए मैं कुछ Oracleज्ञान का उपयोग व्याख्या और व्याख्या करने के लिए करूंगा :-)

चलो संख्या 4946144450195624में परिवर्तित करें binary। उसके लिए मैं एक छोटे functionसे dec2bin यानी दशमलव-से-बाइनरी का उपयोग करता हूं ।

SQL> CREATE OR REPLACE FUNCTION dec2bin (N in number) RETURN varchar2 IS
  2    binval varchar2(64);
  3    N2     number := N;
  4  BEGIN
  5    while ( N2 > 0 ) loop
  6       binval := mod(N2, 2) || binval;
  7       N2 := trunc( N2 / 2 );
  8    end loop;
  9    return binval;
 10  END dec2bin;
 11  /

Function created.

SQL> show errors
No errors.
SQL>

आइए बाइनरी मान प्राप्त करने के लिए फ़ंक्शन का उपयोग करें -

SQL> SELECT dec2bin(4946144450195624) FROM dual;

DEC2BIN(4946144450195624)
--------------------------------------------------------------------------------
10001100100100111110111111110111101100011000010101000

SQL>

अब पकड़ 5-bitरूपांतरण है। प्रत्येक समूह में 5 अंकों के साथ दाएं से बाएं समूह बनाना शुरू करें। हमें मिला :-

100|01100|10010|01111|10111|11111|01111|01100|01100|00101|01000

हम अंत में सिर्फ 3 अंकों के साथ ही उसे छोड़ेंगे। क्योंकि, हमारे पास बाइनरी रूपांतरण में कुल 53 अंक थे।

SQL> SELECT LENGTH(dec2bin(4946144450195624)) FROM dual;

LENGTH(DEC2BIN(4946144450195624))
---------------------------------
                               53

SQL>

hello worldकुल में 11 वर्ण हैं (अंतरिक्ष सहित), इसलिए हमें 2 जोड़ने की आवश्यकता है अंतिम समूह में बिट्स जहां हम समूह बनाने के बाद सिर्फ 3 बिट्स के साथ रह गए थे।

तो, अब हमारे पास है: -

00100|01100|10010|01111|10111|11111|01111|01100|01100|00101|01000

अब, हमें इसे 7-बिट एससीआई मान में बदलने की आवश्यकता है। पात्रों के लिए यह आसान है, हमें केवल 6 वीं और 7 वीं बिट सेट करने की आवश्यकता है। 11बाईं ओर ऊपर प्रत्येक 5-बिट समूह में जोड़ें ।

देता है कि :-

1100100|1101100|1110010|1101111|1110111|1111111|1101111|1101100|1101100|1100101|1101000

आइए द्विआधारी मूल्यों की व्याख्या करते हैं, मैं उपयोग करूंगा binary to decimal conversion function

SQL> CREATE OR REPLACE FUNCTION bin2dec (binval in char) RETURN number IS
  2    i                 number;
  3    digits            number;
  4    result            number := 0;
  5    current_digit     char(1);
  6    current_digit_dec number;
  7  BEGIN
  8    digits := length(binval);
  9    for i in 1..digits loop
 10       current_digit := SUBSTR(binval, i, 1);
 11       current_digit_dec := to_number(current_digit);
 12       result := (result * 2) + current_digit_dec;
 13    end loop;
 14    return result;
 15  END bin2dec;
 16  /

Function created.

SQL> show errors;
No errors.
SQL>

आइए प्रत्येक बाइनरी मूल्य को देखें -

SQL> set linesize 1000
SQL>
SQL> SELECT bin2dec('1100100') val,
  2    bin2dec('1101100') val,
  3    bin2dec('1110010') val,
  4    bin2dec('1101111') val,
  5    bin2dec('1110111') val,
  6    bin2dec('1111111') val,
  7    bin2dec('1101111') val,
  8    bin2dec('1101100') val,
  9    bin2dec('1101100') val,
 10    bin2dec('1100101') val,
 11    bin2dec('1101000') val
 12  FROM dual;

       VAL        VAL        VAL        VAL        VAL        VAL        VAL        VAL        VAL     VAL           VAL
---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
       100        108        114        111        119        127        111        108        108     101           104

SQL>

आइए नजर डालते हैं कि वे कौन से किरदार हैं: -

SQL> SELECT chr(bin2dec('1100100')) character,
  2    chr(bin2dec('1101100')) character,
  3    chr(bin2dec('1110010')) character,
  4    chr(bin2dec('1101111')) character,
  5    chr(bin2dec('1110111')) character,
  6    chr(bin2dec('1111111')) character,
  7    chr(bin2dec('1101111')) character,
  8    chr(bin2dec('1101100')) character,
  9    chr(bin2dec('1101100')) character,
 10    chr(bin2dec('1100101')) character,
 11    chr(bin2dec('1101000')) character
 12  FROM dual;

CHARACTER CHARACTER CHARACTER CHARACTER CHARACTER CHARACTER CHARACTER CHARACTER CHARACTER CHARACTER CHARACTER
--------- --------- --------- --------- --------- --------- --------- --------- --------- --------- ---------
d         l         r         o         w                  o         l         l         e         h

SQL>

तो, हम आउटपुट में क्या प्राप्त करते हैं?

dlrow l ओललेह

यह उल्टा हेल्लोवर्ल्ड है। एकमात्र मुद्दा अंतरिक्ष है । और कारण उनके जवाब में @higuaro द्वारा अच्छी तरह से समझाया गया है। मैं ईमानदारी से पहले प्रयास में अंतरिक्ष के मुद्दे की व्याख्या नहीं कर सका, जब तक कि मैंने उसके उत्तर में दिए गए स्पष्टीकरण को नहीं देखा।


1

PHP में अनुवादित होने पर मुझे कोड समझने में थोड़ा आसान लगा, इस प्रकार है:

<?php

$result=0;
$bignum = 4946144450195624;
for (; $bignum > 0; $bignum >>= 5){
    $result = (( $bignum & 31 | 64) % 95) + 32;
    echo chr($result);
}

लाइव कोड देखें


0

out.println ((char) (((l (31 | 64)% 95) + 32/1002439 * 1002439);

इसे कैप बनाने के लिए: 3


1
आप क्या कर रहे हैं और क्यों कर रहे हैं, इसके बारे में कुछ स्पष्टीकरण जोड़ने पर विचार करें।
फेडोरक्वी 'एसओ स्टॉप' नुकसान
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.