मैंने इस विचित्रता की खोज की:
for (long l = 4946144450195624l; l > 0; l >>= 5)
System.out.print((char) (((l & 31 | 64) % 95) + 32));
आउटपुट:
hello world
यह कैसे काम करता है?
मैंने इस विचित्रता की खोज की:
for (long l = 4946144450195624l; l > 0; l >>= 5)
System.out.print((char) (((l & 31 | 64) % 95) + 32));
आउटपुट:
hello world
यह कैसे काम करता है?
जवाबों:
संख्या 4946144450195624
64 बिट्स फिट होती है, इसका द्विआधारी प्रतिनिधित्व है:
10001100100100111110111111110111101100011000010101000
कार्यक्रम हर 5-बिट समूह के लिए, दाएं से बाएं तक एक चरित्र को डिकोड करता है
00100|01100|10010|01111|10111|11111|01111|01100|01100|00101|01000
d | l | r | o | w | | o | l | l | e | h
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);
}
}
उपरोक्त उत्तरों में कुछ मूल्य जोड़ना। ग्रूवी स्क्रिप्ट के बाद मध्यवर्ती मूल्यों को प्रिंट करता है।
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
दिलचस्प!
मानक 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
कर रहा है।
आपने 5-बिट मानों के रूप में वर्ण एन्कोड किए हैं और उनमें से 11 को 64 बिट लंबे में पैक किया है।
(packedValues >> 5*i) & 31
0-31 की रेंज के साथ i-th एनकोडेड वैल्यू है।
जैसा कि आप कहते हैं, कठिन हिस्सा, अंतरिक्ष को कूट रहा है। निचले मामले के अंग्रेजी अक्षरों में यूनिकोड (और एससीआई, और अधिकांश अन्य एनकोडिंग) में सन्निहित सीमा 97-122 है, लेकिन स्थान 32 है।
इसे दूर करने के लिए, आपने कुछ अंकगणित का उपयोग किया। ((x+64)%95)+32
लगभग उसी तरह है x + 96
(ध्यान दें कि बिटवाइस या इस मामले में इसके बराबर कैसे है), लेकिन जब x = 31 होता है, तो हम प्राप्त करते हैं 32
।
यह एक समान कारण के लिए "हैलो वर्ल्ड" प्रिंट करता है:
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));
बिना ए 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 द्वारा अच्छी तरह से समझाया गया है। मैं ईमानदारी से पहले प्रयास में अंतरिक्ष के मुद्दे की व्याख्या नहीं कर सका, जब तक कि मैंने उसके उत्तर में दिए गए स्पष्टीकरण को नहीं देखा।
out.println ((char) (((l (31 | 64)% 95) + 32/1002439 * 1002439);
इसे कैप बनाने के लिए: 3