Perl/Pack| -1660,13 +1660,6 | 
| http://www.ietf.org/rfc/ien/ien137.txt <mysign(ai,2013-7-3 11:04 am)> | 
| : 아 그러네요, 유래가 거기서 왔다는 것도 예전에 들었었는데 전혀 떠올리지 못하고 이걸 무슨 희한한 숙어인가라고만 생각을... 감사합니다. <mysign([[Raymundo]],2013-7-3 2:26 pm)> | 
| Капха (Вода) производится в верхней части тела в виде слизи в легких и желудке. Лекарства, которые назначают для лечения сыпи, тетрациклин и изотретиноин, даже в нормальных дозах могут быть токсичными для употребляющего анаболики. Пусть все будут счастливы. Все дело в особенности образования изображения. Сильно рекомендую Комментарии к статье Нет комментариев. Становится теплее, как на улице, так и в душе. Добавить комментарий У вас нет полномочий комментировать. Считаете на телефоне или калькуляторе? Эти показатели выражаются в уровне востребованности компании и количестве реализованных проектов. Преобразуем наш сервер в виртуальный. Конечно, классические направления никогда не выйдут из моды и кованые изделия с элементами в виде растительного орнамента всегда востребованы и популярны. Издавна лилии выращивались не только в декоративных, но и в лечебных целях, из этих ароматных цветов делали душистые мази, масла, благовония и настойки. О качестве продукции вы сможете узнать конечно только, когда ее попробуете. Она точно повторяет модель, только в обратной, вогнутой форме. Это единственная часть половой системы женщины, доступная непосредственному осмотру. Если походить в трущобах, то найдёте жилище с запертой дверью. А далее можете дать развернуться своей фантазии и выбирать самые различные цветовые комбинации и варианты оформления. Эти предложения исходят как от достойных компаний, работающих уже не первый год, молодых малоизвестных компаний которые еще не имеют большого опыта работы на рынке. При включении зажигания происходит тестовая проверка исправности индикатора, он загорается и гаснет после запуска двигателя. В этом городе тогда процветали все виды искусства, включая печать. Перерыв дает возможность отдохнуть Вашему мозгу и усвоить накопившийся материал. У многих родителей часто возникает вопрос, есть ли срок годности у подгузников? Мы с моей супругой давно уже нашли ответ на этот вопрос. Если ваши дети часто простужаются — дайте им погреться на теплом песочке и горячих камнях, подышать морским воздухом, наполненным йодом, поплескаться в целебной морской воде. Педагог должен учитывать очередность разыгрывания наиболее привлекательных для детей ролей. Просто кремль бесит, что А. Во времена греков и римлян, когда была популярная одежда с коротким рукавом, были модными браслеты, которые носились на верхней части руки. Входная дверь должна быть: максимально прочной, чтобы ее невозможно было сломать какими-либо предметами или просто выломать плечом надежной, в конструкции двери должны быть продуманы замки, для того, чтобы защитить вашу квартиру от попыток воров украсть ценные вещи из вашей квартиры должна обладать повышенной звукозащитой, чтобы ваш покой не нарушали различные шумы, доносящиеся из подъезда входная дверь должна защищать вашу квартиру также и от запахов, поскольку многие соседи имеют вредную привычку курить в подъезде естественно, входная дверь должна сохранять тепло, даже в холодные морозные дни не стоит игнорировать и внешний вид двери, поскольку при максимальной надежности, она должна гармонично вписываться в окружающий интерьер и общий стиль квартиры необходимо обратить внимание на контроль доступа: в двери обязательно должен быть качественный глазок. Есть одно поле для оставления примечания по конкретной компании и экспорт данных в текстовый файл. Постановлением Совета Министров Республики Беларусь от 02. \\ | 
| <a href=http://akwametron.ru/%D0%B0%D1%80%D0%BC%D0%B5%D0%B9%D1%81%D0%BA%D0%B8%D0%B5-%D0%BF%D0%B0%D1%80%D0%B0%D0%B4%D0%BD%D1%8B%D0%B5-%D0%B1%D1%80%D1%8E%D0%BA%D0%B8-%D0%B2-%D0%BD%D0%BE%D0%B2%D0%BE%D0%BA%D1%83%D0%B7%D0%BD%D0%B5%D1%86%D0%BA%D0%B5>армейские парадные брюки в новокузнецке</a> \\ | 
| <a href=http://akwametron.ru/%D0%BC%D0%BE%D1%89%D0%BD%D1%83%D1%8E-%D0%BA%D0%BE%D1%84%D0%B5%D0%BC%D0%BE%D0%BB%D0%BA%D1%83-%D0%BC%D0%B5%D0%BB%D0%BA%D0%BE%D0%B3%D0%BE-%D0%BF%D0%BE%D0%BC%D0%BE%D0%BB%D0%B0>мощную кофемолку мелкого помола</a> \\ | 
| <a href=http://akwametron.ru/%D0%BC%D0%BE%D0%B6%D0%BD%D0%BE-%D0%BF%D1%80%D0%BE%D0%B5%D0%B7%D0%B4%D0%BD%D0%BE%D0%B9-%D0%BD%D0%B0-%D1%82%D1%80%D0%B0%D0%BC%D0%B2%D0%B0%D0%B9-%D0%B3%D0%B2%D0%BE%D0%BB%D0%B3%D0%BE%D0%B3%D1%80%D0%B0%D0%B4>можно проездной на трамвай гволгоград</a> \\ | 
| <a href=http://akwametron.ru/%D1%84%D0%B8%D0%B3%D1%83%D1%80%D0%BA%D0%B8-%D0%BD%D0%B0-%D1%82%D0%BE%D1%80%D1%82-%D0%BA%D0%B0%D0%BD%D0%B0%D0%B4%D0%B0>фигурки на торт канада</a> \\ | 
| <a href=http://9058735.ru/web-%D0%BA%D0%B0%D0%BC%D0%B5%D1%80%D0%B0-trust-spotlight-webcam-pro-%D0%B2-%D1%83%D0%BA%D1%80%D0%B0%D0%B8%D0%BD%D0%B5>web камера trust spotlight webcam pro в украине</a> <mysign(Williamsmups,2017-1-8 10:07 pm)> | 
| <longcomments(100)> | 
| ---- | 
| Address | big endian(3) Machine | little endian(4) Machine | 
| 1000 | 0x12 | 0x78 | 
| 1001 | 0x34 | 0x56 | 
| 1002 | 0x56 | 0x34 | 
| 1003 | 0x78 | 0x12 | 
| 포맷 | 설명 | 
| c(6),C(7) | 부호형/무부호형 char (8비트 정수) 값 | 
| s(8),S(9) | 부호형/무부호형 short, 언제나 16비트 | 
| l(10),L(11) | 부호형/무부호형 long, 언제나 32비트 | 
| q(12),Q(13) | 부호형/무부호형 quat (64비트 정수) 값 | 
| i(14),I(15) | 부호형/무부호형 정수, 해당 기계의 고유 포맷 | 
| n(16),N(17) | "network"(big endian(18)) 순서의 16/32 비트 값 | 
| v(19),V(20) | "VAX"(little endian(21)) 순서의 16/32 비트 값 | 
| 형식 | 설명 | 
| a(23),A(24) | 널/공백으로 채워지는 스트링 | 
| b(25),B(26) | 오름차순/내림차순 비트 순서로 된 바이너리 스트링 | 
| h(27),H(28) | 낮은/높은 니블3이 먼저 나오는 16진수 스트링 | 
| Z(29) | null로 끝나는 스트링 | 
주인장 보충: 말이 좀 애매하긴 한데, 관련 문서에 있는 aero님의 문서를 참조하면 좀 쉽다. 숫자를 나타내는 c 등에 *가 붙으면, 인자로 주어진 값 리스트의 나머지 원소들을 다 가져와서 pack하게 된다.이제 예제를 하나 만들어보자. 웹 문서의 폼에서 어떤 정보를 수집하여, C로 작성된 백엔드 시스템에 전달하여 처리한다고 가정하자. 이 폼은 직원이 사무용품 지급을 요청할 수 있는 폼이다. 백엔드 시스템은 입력이 다음과 같은 포맷으로 주어져야 한다.$a = pack "c*", "65", "66", "67"; # $a = "ABC", 즉 "66","67"을 다 가져왔다반면에 스트링을 나타내는 a 같은 경우에는 그 문자에 해당하는 원소의 나머지 문자들 전부를 가져온다.$a = pack "a*", "abc", "def", "ghi"; # $a = "abc", 즉 첫번째 값 "abc"의 나머지 문자인 b와 c를 가져왔다
    struct SupplyRequest {
        time_t request_time;    // time request was entered
        int employee_id;        // employee making request
        char item[32];          // item requested
        short quantity;         // quantity needed
        short urgent;           // request is urgent
    };
시스템의 헤더 파일을 봤더니 time_t는 long 타입이다. 백엔드 시스템에 보낼 레코드를 구성하기 위해서, 다음과 같이 할 수 있다.4
$rec = pack( "l i Z32 s2", time, $emp_id, $item, $quan, $urgent);이 템플릿은 "long 하나, int 하나, null로 끝나며 최대길이 32캐릭터인 스트링, short 두 개"를 의미한다. 사원번호 217641(어이! 그건 나잖아!)인 직원이 2003년 1월 1일에 종이클립 두 통을 긴급하게 요청한다면, $rec 변수에는 다음과 같은 값이 담긴다. (첫 줄은 십진수, 두번째 줄은 16진수, 셋째 줄은 해당 값을 문자로 변환할 수 있는 경우 변환된 문자) 각 필드의 경계를 나타내기 위해 파이프 기호를 사용했다.
     오프셋   내용 (주소는 좌측에서 우측으로 커짐)
         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
        16    32 112  97 112 101 114  99 108 105 112 115   0   0   0   0   0
              20  70  61  70  65  72  63  6c  69  70  73  00  00  00  00  00
                   p   a   p   e   r   c   l   i   p   s
        32     0   0   0   0   0   0   0   0|  2   0|  1   0
              00  00  00  00  00  00  00  00| 02  00| 01  00
저것들이 어디서 왔는지 살펴 보자. 템플릿의 첫번째 항목은 'l'이고 이건 long 타입의 값을 pack한다. long은 32비트, 4바이트이다. 저장할 값은 time 함수를 사용하여 얻었다. 실제 값은 1041444000 = 0x3e132ca0이다. 이 값이 버퍼의 시작 부분에 어떻게 들어가는지 보라. 내 시스템은 인텔 펜티엄 프로세서가 달려 있고 little endian(32)이 사용된다.
두번째 템플릿 항목은 'i'이다. 이것은 머신 고유의 크기의 정수를 가져온다. 펜티엄은 32비트 프로세서이고 따라서 이번에도 4바이트로 pack한다. 사원번호는 217641이고 16진수로는 0x00035229이다.
세번째 항목은 'Z32'이다. 이것은 null로 끝나는 32캐릭터 필드를 의미한다. 위의 버퍼를 보면 'boxes of paperclips'가 저장되어 있고 32바이트 중 나머지 부분은 0(널 캐릭터)으로 채워져 있는 것을 볼 수 있다.
마지막 항목은 's2'이다. 이것은 두 개의 short값을 필요로 하고 short값은 16비트 정수이다. 이 항목은 pack에 전달된 값 리스트에서 두 개의 값을 가져온다. 16비트는 두 바이트에 저장된다. 첫번째 값은 2이고 두번째 값은 긴급을 1로서 긴급함을 나타낸다. 이 두 값은 버퍼의 마지막 네 바이트를 차지하고 있다.
    ($order_time, $monk, $itemname, $quantity, $ignore) =
        unpack( "l i Z32 s2", $rec );
여기에 사용된 템플릿이 우리가 pack할 때 사용한 템플릿과 동일하고, 같은 정보가 같은 순서로 반환되는 것에 주목하라.(우리가 pack한 $urgent 변수를 받는데 그들이 $ignore 변수를 사용한 것만 빼면 말이지. 도대체 저 친구들은 무슨 말을 하고 싶은 거지?)
    pack('a8',"hello") produces "hello\0\0\0"
    pack('Z8',"hello") produces "hello\0\0\0"
    pack('A8',"hello") produces "hello   "
    unpack('a8',"hello\0\0\0") produces "hello\0\0\0"
    unpack('Z8',"hello\0\0\0") produces "hello"
    unpack('A8',"hello   ") produces "hello"
    unpack('A8',"hello\0\0\0") produces "hello"
    ord(pack('b8','00100110')) produces 100 (4 + 32 + 64)
    ord(pack('B8','00100110')) produces 38 (32 + 4 + 2)
    pack('h4','1234') produces 0x21,0x43
    pack('H4','1234') produces 0x12,0x34
#!/usr/bin/perl -w use strict; # 스트링의 각 바이트를 10진수, 16진수, 캐릭터로 덤프한다 sub DumpString { my @a = unpack('C*',$_[0]); my $o = 0; while (@a) { my @b = splice @a,0,16; my @d = map sprintf("%03d",$_), @b; my @x = map sprintf("%02x",$_), @b; my $c = substr($_[0],$o,16); $c =~ s/[[:^print:]]/ /g; printf "%6d %s\n",$o,join(' ',@d); print " "x8,join(' ',@x),"\n"; print " "x9,join(' ',split(//,$c)),"\n"; $o += 16; } } # 웹으로 주문을 내린다 my $t = time; my $emp_id = 217641; my $item = "boxes of paperclips"; my $quan = 2; my $urgent = 1; my $rec = pack( "l i a32 s2", $t, $emp_id, $item, $quan, $urgent); DumpString($rec); # 웹으로 들어온 주문을 처리한다 my ($order_time, $monk, $itemname, $quantity, $ignore) = unpack( "l i a32 s2", $rec ); print "Order time: ",scalar localtime($order_time),"\n"; print "Placed by monk #$monk for $quantity $itemname\n"; # 스트링 포맷들 $rec = pack('a8',"hello"); # should produce 'hello\0\0\0' DumpString($rec); $rec = pack('Z8',"hello"); # should produce 'hello\0\0\0' DumpString($rec); $rec = pack('A8',"hello"); # should produce 'hello ' DumpString($rec); ($rec) = unpack('a8',"hello\0\0\0"); # should produce 'hello\0\0\0' DumpString($rec); ($rec) = unpack('Z8',"hello\0\0\0"); # should produce 'hello' DumpString($rec); ($rec) = unpack('A8',"hello "); # should produce 'hello' DumpString($rec); ($rec) = unpack('A8',"hello\0\0\0"); # should produce 'hello' DumpString($rec); # 비트 포맷 $rec = pack('b8',"00100110"); # should produce 0x64 (100) DumpString($rec); $rec = pack('B8',"00100110"); # should produce 0x26 (38) DumpString($rec); # 16진수 포맷 $rec = pack('h4',"1234"); # should produce 0x21,0x43 DumpString($rec); $rec = pack('H4',"1234"); # should produce 0x12,0x34 DumpString($rec);
# $mem에 어떤 바이트 시퀀스 - 내용이 뭐가 됐든 - 가 들어있는 상태에서 my ( $hex ) = unpack( 'H*', $mem ); print "$hex\n"; # 출력예 41204d414e204120504c414e20412043414e414c2050414e414d41반대 동작 - 16진수 숫자들의 스트링을 바이트 덩어리로 압축
my $s = pack( 'H2' x 10, map { "3$_" } ( 0..9 ) ); print "$s\n"; # 출력 0123456789
    Date      |Description                | Income|Expenditure
    01/24/2001 Ahmed's Camel Emporium                  1147.99
    01/28/2001 Flea spray                                24.99
    01/29/2001 Camel rides to tourists      235.00
    while (<>) {
        my $date   = substr($_,  0, 11);
        my $desc   = substr($_, 12, 27);
        my $income = substr($_, 40,  7);
        my $expend = substr($_, 52,  7);
        ...
    }
    while (<>) {
        my($date, $desc, $income, $expend) =
            m|(\d\d/\d\d/\d{4}) (.{27}) (.{7})(.*)|;
        ...
    }
    while (<>) {
        my($date, $desc, $income, $expend) = unpack("A10xA27xA7xA*", $_);
        ...
    }
    my($date) = unpack("A10", $_);
    while (<>) {
        my($date, $desc, $income, $expend) = unpack("A10xA27xA7xA*", $_);
        $tot_income += $income;
        $tot_expend += $expend;
    }
    $tot_income = sprintf("%.2f", $tot_income); # Get them into 
    $tot_expend = sprintf("%.2f", $tot_expend); # "financial" format
    $date = POSIX::strftime("%m/%d/%Y", localtime);
    # OK, let's go:
    print pack("A10xA27xA7xA*", $date, "Totals", $tot_income, $tot_expend);
    print pack("A11 A28 A8 A*", $date, "Totals", $tot_income, $tot_expend);
# 템플릿 스트링 안에 있는 공백은 단지 가독성을 위해 추가한 것이고, 실제 변환시 공백으로 변환되는 것이 아님
    $tot_income = sprintf("%.2f", $tot_income);
    $tot_expend = sprintf("%12.2f", $tot_expend);
    $date = POSIX::strftime("%m/%d/%Y", localtime);
    print pack("A11 A28 A8 A*", $date, "Totals", $tot_income, $tot_expend);
01/24/2001 Ahmed's Camel Emporium 1147.99 01/28/2001 Flea spray 24.99 01/29/2001 Camel rides to tourists 1235.00 11/07/2008 Totals 1235.00 1172.98여기까지의 내용 정리:
pack("A*A*", $one, $two);
my $ps = pack( 's', 20302 );
my( $s ) = unpack( 's', $ps );이것 - pack한 결과를 unpack하면 원래의 값을 얻을 수 있는 것 - 은 기본적으로 수와 관련된 모든 템플릿에 해당되나,
   signed unsigned  byte length in C   byte length in Perl
     s!     S!      sizeof(short)      $Config{shortsize}
     i!     I!      sizeof(int)        $Config{intsize}
     l!     L!      sizeof(long)       $Config{longsize}
     q!     Q!      sizeof(long long)  $Config{longlongsize}
      +---------+        +----+----+               +---------+
 TOS: |   IP    |  TOS+4:| FL | FH | FLAGS  TOS+14:|   SI    |
      +---------+        +----+----+               +---------+
      |   CS    |        | AL | AH | AX            |   DI    |
      +---------+        +----+----+               +---------+
                         | BL | BH | BX            |   BP    |
                         +----+----+               +---------+
                         | CL | CH | CX            |   DS    |
                         +----+----+               +---------+
                         | DL | DH | DX            |   ES    |
                         +----+----+               +---------+
my( $ip, $cs, $flags, $ax, $bx, $cd, $dx, $si, $di, $bp, $ds, $es ) = unpack( 'v12', $frame );
my( $fl, $fh, $al, $ah, $bl, $bh, $cl, $ch, $dl, $dh ) = unpack( 'C10', substr( $frame, 4, 10 ) );
my( $ip, $cs, $flags,$fl,$fh, $ax,$al,$ah, $bx,$bl,$bh, $cx,$cl,$ch, $dx,$dl,$dh, $si, $di, $bp, $ds, $es ) = unpack( 'v2' . ('vXXCC' x 5) . 'v5', $frame );
my $buf = pack( 'N', length( $msg ) ) . $msg; # 또는 아예 묶어서 my $buf = pack( 'NA*', length( $msg ), $msg ); # 이제 $buf를 송신 루틴에 전달
my @data = unpack 's*', pack 'S*', unpack 'n*', $buf;Perl 5.9.2(83)에서는 원하는 바이트-오더를 명시할 수 있는 방법을 제공한다.
my @data = unpack 's>*', $buf;이 변경자들은 C 구조체를 다룰 때 더욱 유용하다.
     7 6 5 4 3 2 1 0
   +-----------------+
   | 1 0 0 0 1 1 0 0 |
   +-----------------+
    MSB           LSB
$byte = pack( 'B8', '10001100' ); # start with MSB $byte = pack( 'b8', '00110001' ); # start with LSBpack은 항상 다음 바이트의 경계에서 시작해서 8의 배수만큼 자르며, 필요하다면 0 비트를 추가해서 채워넣는다. 따라서 비트 필드를 pack,unpack 할 수는 없음. 비트 필드를 다루려면 vec 함수를 쓰거나, unpack해서 얻은 비트 스트링에 split, substr, concatenation 등을 사용하여 캐릭터 스트링 차원에서 처리할 것. unpack 예제 - 상태 레지스터 분해:
   +-----------------+-----------------+
   | S Z - A - P - C | - - - - O D I T |
   +-----------------+-----------------+
    MSB           LSB MSB           LSB
($carry, undef, $parity, undef, $auxcarry, undef, $zero, $sign, $trace, $interrupt, $direction, $overflow) = split( //, unpack( 'b16', $status ) );
my $uubuf = pack( 'u', $bindat );u 뒤에 붙는 카운트는 uuencoding된 라인 하나에 삽입할 바이트 수를 설정. 최대값은 디폴트로 45이고, 그 이하의 정수 중 3의 배수로 설정할 수 있다. unpack은 반복 카운트는 무시.
    my $buf = pack( 'iii', 100, 20, 3 );
    print unpack( '%32i3', $buf ), "\n";  # prints 123
    print unpack( '%32A*', "\x01\x10" ), "\n";  # prints 17
    my $bitcount = unpack( '%32b*', $mask );
    my $evenparity = unpack( '%1b*', $mask );
$UTF8{Euro} = pack( 'U', 0x20AC ); # Equivalent to: $UTF8{Euro} = "\x{20ac}";
$Unicode{Euro} = unpack( 'U', $UTF8{Euro} );
# pack and unpack the Hebrew alphabet my $alefbet = pack( 'U*', 0x05d0..0x05ea ); my @hebrew = unpack( 'U*', $utf );일반적인 경우, Encode::decode_utf8를 사용하여 UTF-8로 인코딩된 바이트 스트링을 Perl 유니코드 스트링으로 디코드하고, Encode::encode_utf8을 써서 Perl 유니코드 스트링을 UTF-8 바이트들로 인코딩하는 것이 좋다. 잘못된 바이트 시퀀스를 처리할 수 있고 인터페이스도 더 친숙하다.
my $berbuf = pack( 'w*', 1, 128, 128+1, 128*128+127 );
unpack( 'v2 (vXXCC)5 v5', $frame )또 다른 예:
join( '', map( substr( $_, 0, 1 ), @str ) )
pack( '(A)'.@str, @str )
pack( '(A)*', @str )
$pd = pack( '(CCS)*', map( @$_, @dates ) );길이가 짝수인 스트링 안에 있는 캐릭터들을 둘씩 짝지은 후 맞바꾸는 예:
$s = pack( '(A)*', unpack( '(xAXXAx)*', $s ) );
$s = pack( '(A)*', unpack( '(@1A @0A @2)*', $s ) );
$s = pack( '(v)*', unpack( '(n)*', $s );
my $msg = pack( 'Z*Z*CA*', $src, $dst, length( $sm ), $sm );
( $src, $dst, $len, $sm ) = unpack( 'Z*Z*CA*', $msg );이 때 문제가 있다. $sm 뒤에 다른 필드를 추가할 경우, pack은 문제가 없지만 unpack을 제대로 할 수 없다.
# pack a message my $msg = pack( 'Z*Z*CA*C', $src, $dst, length( $sm ), $sm, $prio ); # unpack fails - $prio remains undefined! ( $src, $dst, $len, $sm, $prio ) = unpack( 'Z*Z*CA*C', $msg );
# pack a message: ASCIIZ, ASCIIZ, length/string, byte my $msg = pack( 'Z* Z* C/A* C', $src, $dst, $sm, $prio ); # unpack ( $src, $dst, $sm, $prio ) = unpack( 'Z* Z* C/A* C', $msg );
# pack/unpack a string preceded by its length in ASCII my $buf = pack( 'A4/A*', "Humpty-Dumpty" ); # unpack $buf: '13 Humpty-Dumpty' my $txt = unpack( 'A4/A*', $buf );'/(113)'는 Perl 5.6(114)에는 구현되지 않았으므로, 구버전 펄에서 동작하게 하려면 일단 unpack('Z* Z* C')를 하여 길이값을 얻어낸 후에, 그 값을 사용해서 스트링을 다시 unpack해야 한다:
# pack a message: ASCIIZ, ASCIIZ, length, string, byte (5.005 compatible) my $msg = pack( 'Z* Z* C A* C', $src, $dst, length $sm, $sm, $prio ); # unpack ( undef, undef, $len) = unpack( 'Z* Z* C', $msg ); ($src, $dst, $sm, $prio) = unpack ( "Z* Z* x A$len C", $msg );
my $env = pack( '(A*A*Z*)' . keys( %Env ) . 'C', map( { ( $_, '=', $Env{$_} ) } keys( %Env ) ), 0 );
my $n = $env =~ tr/\0// - 1; my %env = map( split( /=/, $_ ), unpack( "(Z*)$n", $env ) );
my $env = pack( 'S(S/A* S/A*)*', scalar keys( %Env ), %Env );반복하는 횟수를 '/(118)'를 사용하여 Unpack할 수 있기 때문에, 역으로 변환하는 과정이 매우 간단해진다:
my %env = unpack( 'S/(S/A* S/A*)', $env );이 예는 pack과 unpack에서 동일한 템플릿을 사용할 수 없는, 드문 경우 중에 한 가지임에 유의할 것. pack에서는 ((119))(120)-그룹의 반복 횟수를 결정할 수 없다.
typedef struct { char c1; short s; char c2; long l; } gappy_t; typedef struct { long l; short s; char c1; char c2; } dense_t;
0 +4 +8 +12 +--+--+--+--+--+--+--+--+--+--+--+--+ |c1|xx| s |c2|xx|xx|xx| l | xx = fill byte +--+--+--+--+--+--+--+--+--+--+--+--+ gappy_t 0 +4 +8 +--+--+--+--+--+--+--+--+ | l | h |c1|c2| +--+--+--+--+--+--+--+--+ dense_t
my $gappy = pack( 'cxs cxxx l!', $c1, $s, $c2, $l );
#include <stdio.h> #include <stddef.h> typedef struct { char fc1; short fs; char fc2; long fl; } gappy_t; #define Pt(struct,field,tchar) \ printf( "@%d%s ", offsetof(struct,field), # tchar ); int main() { Pt( gappy_t, fc1, c ); Pt( gappy_t, fs, s! ); Pt( gappy_t, fc2, c ); Pt( gappy_t, fl, l! ); printf( "\n" ); }
my $gappy = pack( '@0c @2s! @4c @8l!', $c1, $s, $c2, $l );
my $gappy = pack( 'c x!2 s c x!4 l!', $c1, $s, $c2, $l );
my $gappy = pack( 'c x![s] s c x![l!] l!', $c1, $s, $c2, $l );
my $gappy = pack( 'c x![s] s c x![l] l', $c1, $s, $c2, $l );
my $gappy = pack( 'c x![s] s< c x![l] l<', $c1, $s, $c2, $l );
my $gappy = pack( '( c x![s] s c x![l] l )<', $c1, $s, $c2, $l );
typedef struct { short count; char glyph; } cell_t; typedef cell_t buffer_t[BUFLEN];count의 앞, 또는 count와 glyph 사이에 패딩을 할 필요가 없으므로, 간단히 다음과 같이 쓸 지 모른다:
# 뭔가 잘못 되고 있음: pack( 's!a' x @buffer, map{ ( $_->{count}, $_->{glyph} ) } @buffer );
pack( 's!ax' x @buffer, map{ ( $_->{count}, $_->{glyph} ) } @buffer );
typedef struct { char foo[2]; } foo_t;
    # allocate some storage and pack a pointer to it
    my $memory = "\x00" x $size;
    my $memptr = pack( 'P', $memory );
pack이 반환한 것은 바이트의 시퀀스이고, C 코드가 요구하는 것은 포인터, 즉 어떤 수이다. 따라서 pack이 리턴한 바이트 문자열을 숫자로 된 주소로 바꿔야 한다:
    my $ptr = unpack( 'L!', $memptr );
    ssize_t read(int fd, void *buf, size_t count);
    require 'syscall.ph';
    sub cat($){
        my $path = shift();
        my $size = -s $path;
        my $memory = "\x00" x $size;  # allocate some memory
        my $ptr = unpack( 'L', pack( 'P', $memory ) );
        open( F, $path ) || die( "$path: cannot open ($!)\n" );
        my $fd = fileno(F);
        my $res = syscall( &SYS_read, fileno(F), $ptr, $size );
        print $memory;
        close( F );
    }
my $mem = "abcdefghijklmn"; print unpack( 'P5', pack( 'P', $mem ) ); # prints "abcde"
my $buf = pack( 'p', "abc\x00efhijklmn" ); print unpack( 'p', $buf ); # prints "abc"
주인장의 보충: "Pack / Unpack Tutorial"의 마지막 예제 코드에 있는 DumpString를 사용하여 덤프를 출력하며 비교해보자.$x란 변수가 실제로 저장되어 있는데 'p'노 'P' 코드로 pack(..., $x)을 할 때는 신중해야 한다. Perl 내부에서는 변수와 변수의 주소 사이의 관계를 펄만의 비밀스런 방식으로 처리하며, 사용자가 사본을 획득한 것에 대해22 그다지 신경쓰지 않는다. 따라서
- 스트링 데이타를 3개 준비하고
 my $str1 = "ABC\x{41}DEFGHI"; # 널 캐릭터 포함해서 10글자짜리 my $str2 = "abc\x{00}defghi"; my $str3 = "123\x{00}567890";
- P코드 뒤에 길이를 붙이며 pack
 my $pack1 = pack( 'P' , $str1, $str2, $str3 ); my $pack2 = pack( 'P2', $str1, $str2, $str3 ); my $pack3 = pack( 'P*', $str1, $str2, $str3 ); my $pack4 = pack( 'PP', $str1, $str2, $str3 ); my $pack5 = pack( 'P2P3', $str1, $str2, $str3 );
- 덤프를 뜬다
 DumpString( $pack1 ); DumpString( $pack2 ); DumpString( $pack3 ); DumpString( $pack4 ); DumpString( $pack5 );
- 출력은
 0 048 130 084 009 30 82 54 09 0 T 0 048 130 084 009 30 82 54 09 0 T 0 048 130 084 009 30 82 54 09 0 T 0 048 130 084 009 136 081 084 009 30 82 54 09 88 51 54 09 0 T Q T 0 048 130 084 009 136 081 084 009 30 82 54 09 88 51 54 09 0 T Q T
- 처음 셋은 다 동일하다, 'P'는 해당 변수의 주소를 pack하는 것이라서, "길이"란 게 의미가 없다.
 - "PP"로 템플릿을 주었을 때는 $str1과 $str2의 주소가 각각 pack된다.
 - "PP"와 "P2P3"도 서로 동일하다.
 
- 이걸 unpack하자. 리스트의 원소들을 구분하기 위해 "|" 기호로 join하고, 좌우에도 대괄호를 붙여서 공백을 확인할 수 있게 한다.
 print "[", join( '|', unpack( 'P' , $pack1 ) ), "]\n"; # "A" print "[", join( '|', unpack( 'P2' , $pack2 ) ), "]\n"; # "AB" print "[", join( '|', unpack( 'P10', $pack2 ) ), "]\n"; # "ABC\0DEFGHI" print "[", join( '|', unpack( 'P*' , $pack3 ) ), "]\n"; # 런타임에 에러가 난다. print "[", join( '|', unpack( 'PP' , $pack4 ) ), "]\n"; # ( "A", "a" ) print "[", join( '|', unpack( 'P2P3' , $pack4 ) ), "]\n"; # ( "AB", "abc" )
- 출력은
 [A] [AB] [ABCDEFGHI] 'P' must have an explicit size in unpack at ./t07.pl line 25. <- 실제로는 이 시점에서 에러가 나며 프로그램이 종료되므로, 'P*' 라인을 지워야 이하의 출력이 나온다. [A|a] [AB|abc]
- "P"는 "P1"로 간주되는 걸 알 수있다.
 - "P*"는 시작 주소를 주면서 "길이는 최대"라고 주는 셈이라서 의미가 없다. 런타임 에러가 나면서 프로그램이 종료된다.
 - "PP"는 pack되어 있던 두 개의 포인터에서 각각 한 바이트씩을 끄집어낸다.
 - "P2P3"는 두 개의 포인터에서 2바이트, 3바이트씩 가져온다.
 
- 이번에는 "p"를 사용하여 동일하게 pack
 my $pack1 = pack( 'p' , $str1, $str2, $str3 ); my $pack2 = pack( 'p2', $str1, $str2, $str3 ); my $pack3 = pack( 'p*', $str1, $str2, $str3 ); my $pack4 = pack( 'pp', $str1, $str2, $str3 ); my $pack5 = pack( 'p2p3', $str1, $str2, $str3 );
- 덤프를 뜬다.
 DumpString( $pack1 ); DumpString( $pack2 ); DumpString( $pack3 ); DumpString( $pack4 ); DumpString( $pack5 );
- 출력
 0 048 130 084 009 30 82 54 09 0 T 0 048 130 084 009 136 081 084 009 30 82 54 09 88 51 54 09 0 T Q T 0 048 130 084 009 136 081 084 009 176 223 084 009 30 82 54 09 88 51 54 09 b0 df 54 09 0 T Q T T 0 048 130 084 009 136 081 084 009 30 82 54 09 88 51 54 09 0 T Q T 0 048 130 084 009 136 081 084 009 176 223 084 009 232 074 083 009 30 82 54 09 88 51 54 09 b0 df 54 09 e8 4a 53 09 0 T Q T T J S 16 232 074 083 009 e8 4a 53 09 J S
- 'p'는 $str1의 포인터를 pack
 - 'p2'는 'p'와 다르다. $str1, $str2의 포인터를 pack한다
 - 'p*'는 뒤에 오는 리스트 전부를 받아들이니 총 3개의 포인터
 - 'pp'는 'p2'와 같다
 - 'p2p3'는 좀 묘하다. 'ppppp'와 같은 상황이니 변수 3개의 포인터가 앞에 pack되는 데, 그 뒤에 8바이트가 더 있다. 포인터 두개가 더 들어가 있는 듯 한데, 둘은 같은 값이다.
 
- unpack해보자.
 print "[", join( '|', unpack( 'p' , $pack1 ) ), "]\n"; print "[", join( '|', unpack( 'p2' , $pack2 ) ), "]\n"; print "[", join( '|', unpack( 'p10', $pack2 ) ), "]\n"; print "[", join( '|', unpack( 'p*' , $pack3 ) ), "]\n"; print "[", join( '|', unpack( 'pp' , $pack4 ) ), "]\n"; print "[", join( '|', unpack( 'p2p3' , $pack5 ) ), "]\n";
- 출력
 [ABC] [ABC|abc] [ABC|abc] [ABC|abc|123] [ABC|abc] [ABC|abc|123||]
- 'p'는 길이가 명시되지 않아서 널 캐릭터가 있는 곳까지 세 글자를 가져온다.
 - 'p2'는 포인터 두개에서 세 글자를 가져온다.
 - 'p10'을 해봤자 실제 pack되어 있는 포인터는 두개뿐이니 'p2'와 같은 출력
 - 'p*'는 pack되어 있는 모든 포인터에서 스트링을 가져온다.
 - 'pp'는 'p2'와 같다
 - 'p2p3'는 'ppppp'와 같고, 처음 세 포인터에서 세 글자씩 가져오고, 나머지 두 포인터를 가지고도 unpack하여 원소가 두 개 더 반환되었다. 실제로 뭐를 가리키는지 몰라도, 아무것도 출력되지 않았다.
 
    # IP 주소를 소켓 함수에 인자로 줄 수 있는 형태로 변환
    pack( "C4", split /\./, "123.4.5.6" );
    # 어떤 메모리 영역 내에서 1인 비트의 수 합산
    unpack( '%32b*', $mask );
    # 시스템이 어떤 엔디안을 사용하고 있는지 검사
    $is_little_endian = unpack( 'c', pack( 's', 1 ) );
    $is_big_endian = unpack( 'xc', pack( 's', 1 ) );
    # 시스템 고유의 integer 타입이 몇 비트를 차지하는지 검사
    $bits = unpack( '%32I!', ~0 );
    # nanosleep 시스템 호출의 인자를 준비
    my $timespec = pack( 'L!L!', $secs, $nanosecs );
주인장 보충: 위 예 중에# 시스템 고유의 integer 타입이 몇 비트를 차지하는지 검사 $bits = unpack( '%32I!', ~0 );이것은 제대로 동작하지 않는다(적어도 주인장이 테스트한 Perl 5.8.8에서는 그랬다). 아래처럼 바꿔야 한다.$bits = unpack( '%32B*', pack( 'I!', ~0 ) );
    # 어디에서 숫자를 끌어왔을까...
    print unpack( 'C', pack( 'x' ) ),
          unpack( '%B*', pack( 'A' ) ),
          unpack( 'H', pack( 'A' ) ),
          unpack( 'A', unpack( 'C', pack( 'A' ) ) ), "\n";
    # 이별을 하며 건배를 ;-)
    my $advice = pack( 'all u can in a van' );
    unpack 'W/a', "\04Gurusamy";            gives ('Guru')
    unpack 'a3/A A*', '007 Bond  J ';       gives (' Bond', 'J')
    unpack 'a3 x2 /A A*', '007: Bond, J.';  gives ('Bond, J', '.')
    pack 'n/a* w/a','hello,','world';       gives "\000\006hello,\005world"
    pack 'a/W2', ord('a') .. ord('z');      gives '2ab'
        print length(pack("s")), " ", length(pack("s!")), "\n";
        print length(pack("l")), " ", length(pack("l!")), "\n";
       use Config;
       print $Config{shortsize},    "\n";
       print $Config{intsize},      "\n";
       print $Config{longsize},     "\n";
       print $Config{longlongsize}, "\n";
        0x12 0x34 0x56 0x78     # big-endian
        0x78 0x56 0x34 0x12     # little-endian
        0x56 0x78 0x12 0x34
        0x34 0x12 0x78 0x56
        print join(" ", map { sprintf "%#02x", $_ }
                            unpack("W*",pack("L",0x12345678))), "\n";
        use Config;
        print $Config{byteorder}, "\n";
    pack( '@1A((@2A)@3A)', 'a', 'b', 'c' )
is the string "\0a\0\0bc".
    $foo = pack("WWWW",65,66,67,68);
    # foo eq "ABCD"
    $foo = pack("W4",65,66,67,68);
    # same thing
    $foo = pack("W4",0x24b6,0x24b7,0x24b8,0x24b9);
    # same thing with Unicode circled letters.
    $foo = pack("U4",0x24b6,0x24b7,0x24b8,0x24b9);
    # same thing with Unicode circled letters. You don't get the UTF-8
    # bytes because the U at the start of the format caused a switch to
    # U0-mode, so the UTF-8 bytes get joined into characters
    $foo = pack("C0U4",0x24b6,0x24b7,0x24b8,0x24b9);
    # foo eq "\xe2\x92\xb6\xe2\x92\xb7\xe2\x92\xb8\xe2\x92\xb9"
    # This is the UTF-8 encoding of the string in the previous example
    $foo = pack("ccxxcc",65,66,67,68);
    # foo eq "AB\0\0CD"
    # note: the above examples featuring "W" and "c" are true
    # only on ASCII and ASCII-derived systems such as ISO Latin 1
    # and UTF-8.  In EBCDIC the first example would be
    # $foo = pack("WWWW",193,194,195,196);
    $foo = pack("s2",1,2);
    # "\1\0\2\0" on little-endian
    # "\0\1\0\2" on big-endian
    $foo = pack("a4","abcd","x","y","z");
    # "abcd"
    $foo = pack("aaaa","abcd","x","y","z");
    # "axyz"
    $foo = pack("a14","abcdefg");
    # "abcdefg\0\0\0\0\0\0\0"
    $foo = pack("i9pl", gmtime);
    # a real struct tm (on my system anyway)
    $utmp_template = "Z8 Z8 Z16 L";
    $utmp = pack($utmp_template, @utmp1);
    # a struct utmp (BSDish)
    @utmp2 = unpack($utmp_template, $utmp);
    # "@utmp1" eq "@utmp2"
    sub bintodec {
        unpack("N", pack("B32", substr("0" x 32 . shift, -32)));
    }
    $foo = pack('sx2l', 12, 34);
    # short 12, two zero bytes padding, long 34
    $bar = pack('s@4l', 12, 34);
    # short 12, zero fill to position 4, long 34
    # $foo eq $bar
    $baz = pack('s.l', 12, 4, 34);
    # short 12, zero fill to position 4, long 34
    $foo = pack('nN', 42, 4711);
    # pack big-endian 16- and 32-bit unsigned integers
    $foo = pack('S>L>', 42, 4711);
    # exactly the same
    $foo = pack('s<l<', -42, 4711);
    # pack little-endian 16- and 32-bit signed integers
    $foo = pack('(sl)<', -42, 4711);
    # exactly the same
unpack()에서도 일반적으로 동일한 템플릿이 사용된다.
| * 187 | Endian   33 big endian 1, 3, 18, 61, 75, 82, 85, 156, 158, 183 little endian 2, 4, 21, 32, 35, 62, 71, 87, 128, 160, 162, 185  | Floating Point Number 88 | Integer 34, 60 | 
| Perl version    5.10 136 5.6 48, 114 5.8 47, 49, 104 5.9.2 83  | repeat count 30, 107, 135, 186 | string 22, 36, 96, 101, 111 | Template   5 ! 123, 181 % 97 > 84, 182 < 86, 184 ( 105, 115, 119, 180 ) 106, 116, 120 * 31, 51, 54, 59, 117, 131 . 179 / 112, 113, 118 @ 110, 124, 178 [ 126 ] 127 A 24, 38, 42, 52, 56, 57, 138 a 23, 37, 40, 137 B 26, 44, 93, 99, 141 b 25, 43, 94, 98, 140 C 7, 73, 145 c 6, 144 D 91, 168 d 90, 166 F 92, 167 f 89, 165 H 28, 46, 50, 143 h 27, 45, 142 I 15, 70, 154 i 14, 69, 153 J 164 j 163 L 11, 66, 150 l 10, 65, 122, 149 N 17, 77, 79, 157 n 16, 76, 78, 155 P 129, 130, 133, 170 p 132, 134, 169 Q 13, 68, 152 q 12, 67, 151 S 9, 148 s 8, 63, 64, 147 U 102, 173 u 95, 171 V 20, 81, 161 v 19, 72, 80, 159 W 146 w 103, 175 X 74, 109, 177 x 53, 55, 58, 108, 121, 176 x!N 125 Z 29, 39, 41, 139  | 
| Unicode 100, 174 | uuencode 172 | 
big/little endian 이라는 표현은 걸리버 여행기에서 소인국 사람들이 달걀을 깨뜨리는 방법을 논쟁하는 장면에서 유래한 것이거든요. 자세한 내용은 아래 페이지에서 확인하실 수 있습니다.
http://en.wikipedia.org/wiki/Endianness
http://www.ietf.org/rfc/ien/ien137.txt