এই মুদ্রণটি কীভাবে "হ্যালো ওয়ার্ল্ড" হয়?


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
@ অলি এর জন্য একটি টুপি থাকা উচিত।
সোটিরিওস ডেলিমনলিস

12
এই জাতীয় প্রশ্নগুলি, যা ডাটাবেসের উন্নতি করে না তবে কেবলমাত্র ক্লিকবাইট হিসাবে বিদ্যমান, ভবিষ্যতে হাট খেলাটি বাতিল করার একটি নিশ্চিত-আগুনের উপায়। অনুগ্রহ করে গেমটি নষ্ট করে না
ব্লেজমোনজার

উত্তর:


256

সংখ্যাটি 4946144450195624b৪ বিটের ফিট করে, এর বাইনারি উপস্থাপনাটি হ'ল:

 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⁵ = 32 টি অক্ষর উপস্থাপন করতে পারা যায়। ইংরেজী বর্ণমালাতে 26 টি বর্ণ রয়েছে, এটি অক্ষর বাদে 32 - 26 = 6 টি চিহ্নের জন্য জায়গা করে। এই কোডিফিকেশন স্কিমের সাহায্যে আপনার কাছে সমস্ত 26 টি (একটি কেস) ইংরেজি বর্ণ এবং 6 টি চিহ্ন থাকতে পারে (এর মধ্যে স্থান হচ্ছে)।

অ্যালগরিদমের বিবরণ

>>= 5জন্য-লুপ গ্রুপে গ্রুপ থেকে জাম্প, তারপর 5-বিট গ্রুপ মাস্ক সংখ্যা ANDing বিচ্ছিন্ন পরার 31₁₀ = 11111₂বাক্যেl & 31

কোডটি এর সাথে সম্পর্কিত 7-বিট আসকি চরিত্রটির জন্য 5-বিট মানকে মানচিত্র করে। এটি কৌশলপূর্ণ অংশ, নীচের সারণিতে ছোট বর্ণমালার অক্ষরের জন্য বাইনারি উপস্থাপনা পরীক্ষা করুন:

  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

এখানে আপনি দেখতে পাচ্ছেন যে আমরা যে অ্যাস্কি অক্ষরগুলি মানচিত্র করতে চাইছি তা 7th ম এবং 6th ষ্ঠ বিট সেট ( 11xxxxx₂) দিয়ে শুরু হবে (স্থান বাদে, কেবলমাত্র 6th ষ্ঠ বিট রয়েছে), আপনি ( ) ORদিয়ে 5-বিট কোডিং করতে পারেন এবং এটি হওয়া উচিত ম্যাপিংয়ের জন্য যথেষ্ট, কিন্তু এটি স্থানের জন্য কাজ করবে না (স্পেস স্পেস!)9696₁₀ = 1100000₂

এখন আমরা জানি যে অন্যান্য চরিত্রগুলির একই সময়ে স্থান প্রক্রিয়া করার জন্য বিশেষ যত্ন নেওয়া উচিত। এটি অর্জনের জন্য, কোডটি একটি OR বা 64 64₁₀ = 1000000₂( l & 31 | 64) সহ নিষ্কাশিত 5-বিট গোষ্ঠীতে 7 তম বিটটি (তবে 6 তম নয়) তে পরিণত করে ।

এখন পর্যন্ত 5-বিট গ্রুপটি ফর্মের: 10xxxxx₂(স্থানটি হবে 1011111₂ = 95₁₀)। আমরা যদি 0অন্য মানগুলিকে অপ্রত্যাশিত করতে স্থান মানচিত্র করতে পারি , তবে আমরা the ষ্ঠ বিট চালু করতে পারি এবং এটি সমস্ত হওয়া উচিত। এখানে mod 95অংশটি কী খেলতে আসে তা হল, স্থানটি 1011111₂ = 95₁₀, (l & 31 | 64) % 95)কেবলমাত্র অপারেশন ব্যবহার করে কেবল স্থানটি ফিরে যায় 0এবং এর পরে কোডটি 32₁₀ = 100000₂ পূর্ববর্তী ফলাফলটিতে যুক্ত করে 6th ষ্ঠ বিটটি চালু করে , ((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
ইয়াজান

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 বিটের সংমিশ্রণটি কী তা খুঁজে পেতে পারেন) এবং তারপরে সমস্ত বিট একটি বৃহত সংখ্যক গঠনের জন্য একত্রিত হয়।

ইতিবাচক দীর্ঘতরগুলি bit৩ বিট সংখ্যা, 12 টি অক্ষরের এনক্রিপ্ট হওয়া ফর্মটি ধারণ করতে যথেষ্ট বড়। সুতরাং এটি ধরে রাখার পক্ষে যথেষ্ট বড় Hello word, তবে বৃহত্তর পাঠ্যের জন্য আপনি আরও বড় সংখ্যা বা একটি বিগইন্টিজার ব্যবহার করতে পারেন।


একটি অ্যাপ্লিকেশনটিতে আমরা দৃশ্যমান ইংরেজি অক্ষর, পারস্য অক্ষর এবং প্রতীক এসএমএসের মাধ্যমে স্থানান্তর করতে চেয়েছিলাম। আপনি যেমন দেখতে পাচ্ছেন সেখানে 32 (number of Persian chars) + 95 (number of English characters and standard visible symbols) = 127সম্ভাব্য মান রয়েছে যা b বিট দিয়ে উপস্থাপন করা যেতে পারে।

আমরা প্রতিটি ইউটিএফ -8 (16 বিট) অক্ষরটিকে 7 বিটে রূপান্তর করেছি এবং 56% এরও বেশি সংকোচন অনুপাত পেয়েছি। সুতরাং আমরা একই সংখ্যক এসএমএসে দ্বিগুণ দৈর্ঘ্যের পাঠ্য প্রেরণ করতে পারি। (এটি এখানে একরকম ঘটেছিল)।


ওপির কোডটিতে আরও অনেক কিছু চলছে। উদাহরণস্বরূপ, এটি আসলে কী | 64করছে তা ব্যাখ্যা করে না ।
টেড হপ

1
@ আমির: প্রকৃতপক্ষে 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 পরিসীমা সহ আই-থ্রি এনকোড হওয়া মান।

আপনি যেমন বলছেন, শক্ত অংশটি স্থানটি এনকোড করছে। নিম্ন বর্ণের ইংরেজি অক্ষরগুলি ইউনিকোডে (এবং আসকি এবং অন্যান্য এনকোডিংগুলি) 97-122 এর সামঞ্জস্যপূর্ণ পরিসর দখল করে তবে স্থানটি 32।

এটি কাটিয়ে উঠতে আপনি কিছু গাণিতিক ব্যবহার করেছেন। ((x+64)%95)+32প্রায় সমান x + 96( যেমনটি কীভাবে বিটওয়্যার বা এটি সংখ্যার সমতুল্য তা নোট করুন), তবে যখন এক্স = 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
আপনি অন্য একটি ধাঁধা পোস্ট করার পরিবর্তে আপনি কী করছেন তা ব্যাখ্যা করা উচিত
আলেকজান্ডার ডাবিনস্কি

1
আমি আপনাকে পরামর্শ দিচ্ছি যে আপনি কোনও সাইট (সম্ভবত কিছু বিটা স্ট্যাকএক্সচেঞ্জ?) সন্ধানের জন্য কিছু প্রচেষ্টা বিনিয়োগ করুন যেখানে মজাদার ধাঁধা অবদানকে স্বাগত। স্ট্যাক ওভারফ্লো কঠোরভাবে প্রয়োগ করা ফোকাস সহ একটি প্রশ্নোত্তর সাইট।
মার্কো টপলনিক

1
@ মারকো টপলনিক আমি এমন এক পৃথিবীতে বেড়াতে ঘৃণা করব যেখানে সমস্ত বিধি বা ফোকাস এত কঠোরভাবে প্রয়োগ করা হয়েছিল যাতে কখনও কোনও ব্যতিক্রমকে অনুমতি না দেয়। এসও-তে এরকম অসংখ্য ব্যতিক্রম রয়েছে তা উল্লেখ করার দরকার নেই।
0

1
আমিও চাইব, তবে এসও এমন একটি জগতে অস্বাভাবিকভাবে অনেক বেশি। অবশ্যই এখানে ব্যতিক্রম আছে, তবে তারা স্বাগত জানায় না ।
মার্কো টোপলনিক

1
আরও 15 জন আলেকজান্ডারের ভাব প্রকাশ করেছেন। এবং আপনি সঠিকভাবে বলেছেন যে প্রশ্নটি নিজেই এসও এর পক্ষে অনুপযুক্ত, এর নীচে মন্তব্য করা হয়েছে।
মার্কো টপলনিক

3

Oracleট্যাগ ছাড়াই এই প্রশ্নটি দেখা মুশকিল। সক্রিয় অনুগ্রহ আমাকে এখানে এনেছে। আমি আশা করি প্রশ্নটির অন্যান্য প্রাসঙ্গিক প্রযুক্তি ট্যাগও ছিল :-(

আমি বেশিরভাগ ক্ষেত্রেই কাজ করি Oracle database, তাই আমি Oracleব্যাখ্যা এবং ব্যাখ্যা করতে কিছু জ্ঞান ব্যবহার করব :-)

নম্বর রূপান্তর করা যাক 4946144450195624মধ্যে binary। এর জন্য আমি functionডেসিমিন টু-বাইনারি নামে একটি ছোট ডেস্কবিন ব্যবহার করি ।

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 ডিজিট দিয়ে বামে যাব। কারণ, বাইনারি রূপান্তরটিতে আমাদের মোট সংখ্যা ছিল।

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-বিট আসকি মানে রূপান্তর করতে হবে। চরিত্রগুলির জন্য এটি সহজ, আমাদের কেবল 6th ষ্ঠ এবং 7th ম বিট সেট করতে হবে। যোগ 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 ⌂ leleh

এটি হ্যালো ওয়ার্ল্ড বিপরীত। একমাত্র বিষয় স্থান । এবং কারণটি উত্তরটি @ হিগুয়ারো দ্বারা ভালভাবে ব্যাখ্যা করা হয়েছে। আমি তার উত্তরটিতে প্রদত্ত ব্যাখ্যা না পাওয়া পর্যন্ত আমি প্রথম প্রয়াসে স্পেস ইস্যুটির সত্যতা ব্যাখ্যা করতে পারিনি।


1

নীচের মতো পিএইচপি তে অনুবাদ করলে কোডটি বুঝতে কিছুটা সহজলভ্য হয়েছি:

<?php

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

লাইভ কোড দেখুন


আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.