2010-03-11 5 views
5

मेरे पास एक हेक्स स्ट्रिंग (लंबाई 48 वर्ण) है जो मैं pack फ़ंक्शन के साथ कच्चे बाइट्स में कनवर्ट करना चाहता हूं ताकि इसे Win32 वेक्टर बाइट्स में रखा जा सके।पर्ल का उपयोग करके 48 हेक्स स्ट्रिंग को बाइट्स में कैसे परिवर्तित कर सकता हूं?

मैं पर्ल के साथ यह कैसे कर सकता हूं?

उत्तर

4

कदम हैं: स्ट्रिंग से हेक्साडेसिमल पात्रों में से

  1. निकालें जोड़े।
  2. प्रत्येक जोड़ी को दशमलव संख्या में बदलें।
  3. संख्या को बाइट के रूप में पैक करें।

उदाहरण के लिए:

use strict; 
use warnings; 

my $string = 'AA55FF0102040810204080'; 
my @hex = ($string =~ /(..)/g); 
my @dec = map { hex($_) } @hex; 
my @bytes = map { pack('C', $_) } @dec; 

या, अधिक दृढ़तापूर्वक व्यक्त किया:

use strict; 
use warnings; 

my $string = 'AA55FF0102040810204080'; 
my @bytes = map { pack('C', hex($_)) } ($string =~ /(..)/g); 
+0

धन्यवाद कैसे मैं स्ट्रिंग – ron

+0

को @bytes से रिवर्स आपरेशन कर सकता है यह सही ढंग से काम नहीं करता है। यह पैक करता है: aa: 20: 55: 20: ff: 20: 01: 20: 02: 20: 04: 20: 08: 20: 10: 20: 20: 20: 40: 20: 80 क्यों सभी 20s क्या आप वहां मौजूद हैं??? – poosliver

+0

@poosliver: पैक किए गए डेटा में गैर-प्रिंट करने योग्य वर्ण होते हैं। आप जो देखते हैं उस पर निर्भर करेगा कि आपने इसे कैसे मुद्रित किया है; मुझे नहीं पता कि आपने क्या किया। डेटा :: डंप द्वारा प्रिंट किए गए '@ बाइट्स 'का मान (जो गैर-प्रिंट करने योग्य पात्रों के लिए भागने के दृश्यों का उपयोग करता है)' "\ xAA", "यू", "\ xFF", "\ 1", "\ 2" , "\ 4", "\ b", "\ 20", "", "\ @", "\ x80" '। –

21
my $bytes = pack "H*", $hex; 

अधिक जानकारी के लिए perlpacktut देखें।

+6

मुझे उस ट्यूटोरियल से नफरत है। इसे इतना जटिल क्यों होना चाहिए। वे मेरे $ s = पैक ('एच 2' एक्स 10, मानचित्र {"3 $ _"} (0..9) क्यों देते हैं); मेरे ($ हेक्स) = अनपैक ('एच *', $ mem) के विपरीत 'के रूप में); मुझे गंभीरता से लगता है कि वे जितना संभव हो उतना चीजों को मजबूत करना पसंद करते हैं। – Myforwik

1

मैं स्ट्रिंग है:

"61 62 63 64 65 67 69 69 6a"

जो मैं हेक्स मान के रूप में व्याख्या, और ASCII वर्ण के रूप में उन (उन मूल्यों को चरित्र स्ट्रिंग "abcdefghij" पुन: पेश करना चाहिए) प्रदर्शित करना चाहते हैं।

आमतौर पर, मैं इस तरह जल्दी कुछ लिखने की कोशिश:

$ echo "61 62 63 64 65 67 69 69 6a" | perl -ne 'print "$_"; print pack("H2 "x10, $_)."\n";' 
61 62 63 64 65 67 69 69 6a 
a 

... और फिर मुझे आश्चर्य है कि क्यों मैं केवल एक चरित्र वापस :)

पहले मिलता है, मुझे नीचे ध्यान दें कि चलो _ (नायब

$ echo -n "61 62 63 64 65 67 68 69 6a" | hexdump -C 
00000000 36 31 20 36 32 20 36 33 20 36 34 20 36 35 20 36 |61 62 63 64 65 6| 
00000010 37 20 36 38 20 36 39 20 36 61     |7 68 69 6a| 
0000001a 

: स्ट्रिंग मेरे पास है, यह भी बाइट्स की हेक्स मान है कि यह स्मृति में लेता है के रूप में प्रतिनिधित्व किया जा सकता है अनिवार्य रूप से, मैं "ग करना चाहते हैं onvert "इनपुट के रूप में स्मृति में ऊपर बाइट मूल्यों, इन नीचे वालों के लिए, अगर hexdump द्वारा देखी:

$ echo -n "abcdefghij" | hexdump -C 
00000000 61 62 63 64 65 66 67 68 69 6a     |abcdefghij| 
0000000a 

... जो है कैसे इनपुट हेक्स स्ट्रिंग के लिए मूल मूल्यों को प्राप्त किया गया। ) _

खैर, यह Pack/Unpack Tutorial (AKA How the System Stores Data) पता चला है के रूप में यह उल्लेख है, सबसे मेरे लिए उपयोगी है:

पैक समारोह एक टेम्पलेट स्ट्रिंग और मानों की सूची को स्वीकार करता है [...]

$rec = pack("l i Z32 s2", time, $emp_id, $item, $quan, $urgent);

यह एक अदिश प्रारूपों टेम्पलेट में निर्दिष्ट के अनुसार संग्रहीत मानों की सूची से युक्त रिटर्न [...]

$rec में निम्नलिखित (दशमलव में पहली पंक्ति, हेक्स में दूसरा, तीसरा वर्ण लागू होने पर) होगा।पाइप वर्ण फ़ील्ड सीमाओं को इंगित करते हैं।

 Offset Contents (increasing addresses left to right) 
     0 160 44 19 62| 41 82 3 0| 98 111 120 101 115 32 111 102 
       A0 2C 13 3E| 29 52 03 00| 62 6f 78 65 73 20 6f 66 
              | b o x e s  o f

यही है, मेरे मामले में, $_ एक एकल स्ट्रिंग चर रहा है - जबकि pack इनपुट के रूप में एक स्वरूपण टेम्पलेट स्ट्रिंग के लिए कई तरह के 'एकल' चर का एक सूची (अलावा उम्मीद); और फिर एक 'सिंगल' वैरिएबल आउटपुट करता है (हालांकि, स्मृति का एक बड़ा हिस्सा हो सकता है!)। मेरे मामले में, यदि आउटपुट 'सिंगल' चर में स्मृति में प्रत्येक बाइट में ASCII कोड होता है, तो मैं पूरी तरह से सेट हूं (मैं बस आउटपुट वैरिएबल को सीधे प्रिंट कर सकता हूं)।

इस प्रकार, आदेश $_ स्ट्रिंग से चरों की सूची प्राप्त करने के लिए बस split यह अंतरिक्ष संकेत पर, मैं यह कर सकते हैं - हालांकि, ध्यान दें:

$ echo "61 62 63 64 65 67 68 69 6a" | perl -ne 'print "$_"; print pack("H2", split(/ /, $_))."\n";' 
61 62 63 64 65 67 68 69 6a 
a 

... तत्वों की उस राशि pack होने के लिए एड निर्दिष्ट होना चाहिए (अन्यथा हम केवल एक चरित्र वापस प्राप्त करते हैं); तो, इन विकल्पों में से किसी काम:

$ echo "61 62 63 64 65 67 68 69 6a" | perl -ne 'print "$_"; print pack("H2"x10, split(/ /, $_))."\n";' 
61 62 63 64 65 67 68 69 6a 
abcdeghij 

$ echo "61 62 63 64 65 67 68 69 6a" | perl -ne 'print "$_"; print pack("(H2)*", split(/ /, $_))."\n";' 
61 62 63 64 65 67 68 69 6a 
abcdeghij