PHP Pack && Unpack functions

Source: Internet
Author: User
Tags unpack

refer to a set of function pack,unpack before looking at the following example. Any language with socket operation has a function dedicated to the package, PHP is no exception of course this set of functions is not just a package.
Here's a quick introduction:
Application One:
Enter 16 binary or 2 binary streams.
<?php
$SRC = "3b06";
$binvar = Pack (' h* ', $src);
Echo $binvar;
?>

Look at this program, equivalent to the following program
echo chr (0x3B). chr (0x06);

It's easier to do that later when the amount of data is small. But when it comes to large amounts of data, the previous approach is more practical and less code-intensive.

Cases:
@pairs =split (/&/, $query);
foreach $pairs (@pairs) {
($name, $value) =split (/=/, $pairs);
$value =~tr/+//;
$value =~s/% ([a-fa-f0-9][a-fa-f0-9])/pack ("C", Hex ($))/eg;
$FORM {$name}= $value;
}

Explain:
Pack TEMPLATE, LIST

This function receives a LIST of ordinary Perl values and converts them into a byte string based on the TEMPLATE and returns the string. The parameter list is populated or truncated when necessary. In other words, if you provide fewer parameters than the TEMPLATE requires, the pack assumes that the missing is null. If you provide more parameters than the TEMPLATE requires, then the extra parameters are ignored. A format element that is not recognized in the TEMPLATE will throw an exception.

This template describes the structure of the string as a sequence of fields. Each field is represented by a character that describes the type of the value and its encoding. For example, a format character N declares a four-byte unsigned integer, and the byte order is a large head in front.

Fields are packaged in the order given in the template. For example, if you want to wrap a one-byte unsigned integer and a single-precision floating-point value into a string, you say:
$string = Pack ("CF", 244, 3.14);

The value of the first byte of the returned string is 244. The remaining bytes are 3.14 encoded as single-precision floating-point numbers. The exact encoding of a floating-point number depends on the hardware of your computer.

Some of the important things to consider when packaging are:
The type of data (for example, integer or floating point or string),
The range of values (such as whether your integer is in one, two, four, or even eight bytes, or if you are wrapping a 8-character or Unicode character). ),
Are your integers signed or unsigned, and
The encoding used (for example, the native, the wrapper bits and bytes when the small head is in front, or the top is in front).

Table 29-3 lists the format characters and their meanings. (Other characters may also appear in the format; they are described later.) )

Table 29-3,pack/unpack character meaning
A a filled empty byte string
A a byte string that fills a space
b A bit string, in which the order of bits in each byte is ascending
B a bit string, in which the order of bits in each byte is descending
c A signed char (8-bit integer) value
C an unsigned char (8-bit integer) value; about Unicode See U
D double-precision floating-point number in native format
F single-precision floating-point number in native format
h a hexadecimal string, low four bits in front
H a hexadecimal string, high four bits in front
I a signed integer value, native format
I an unsigned integer value, native format
L A signed long shaping, always 32 bits
L An unsigned long shaping, always 32 bits
N A 16-bit short shaping, "Network" byte order (head in front)
N a 32-bit short shaping, "Network" byte order (head in front)
p A pointer to a string with a null end
P A pointer to a fixed-length string
Q A signed four times-fold (64-bit integer) value
Q an unsigned four times-fold (64-bit integer) value
s a signed short integer value, always 16 bits
S an unsigned short integer value, always 16 bits
U a non-encoded string
U a Unicode character number
V A "VAX" byte sequence (small head in front) of a 16-bit short integer
V a "VAX" byte sequence (small head in front) of a 32-bit short integer
W a BER-compressed integer
X an empty byte (ignoring one byte forward)
X Backup of one byte
Z a null-terminated (and empty-filled) byte string
@ Fill absolute position with empty bytes


You can use blanks and annotations freely in your TEMPLATE. The comment begins with the usual # symbol and extends to the first newline character in the TEMPLATE, if one exists.

Each letter can be followed by a number, indicating count (count), interpreted as a form of repetition count or length, depending on the format. In addition to A,a,b,b,h,h,p, and Z, Count is the number of repetitions in all formats, so the pack eats so many values from the LIST. If Count is a * means all that remains.

The A,a and Z formats only eat a numeric value, but it is packaged as a count-length byte string and filled with empty or blank space as needed. At the time of unpacking, a drew the trailing space and empty, Z drew everything behind the first empty, and a returned the text data unchanged. When packing, a and Z are the same.

Similarly, the B and B formats package a bit string with a length of count. Each byte in the input field generates 1 bits in the result based on the lowest bit of each input byte (that is, Ord ($byte)% 2). Conveniently, this means that bytes 0 and 1 generate bits 0 and 1. From the beginning of the input string, each 8 bytes is converted to one byte of output. If the length of the input string cannot be divisible by 8, then the remaining portion is 0 padded. Similarly, when uppack, any additional bits are ignored. If the input string is longer than required, then the extra part is ignored. Count If yes * means all bytes of the input field are used. At the time of unpacking, these bits are converted to a string consisting of 0 and 1.

The H and H formats are packaged one by count of half bytes (4-bit groups, commonly used to represent hexadecimal bits. ) to make up a string.

The P format packages a string that points to an empty end. It is your responsibility to ensure that the string is not a temporary value (because the temporary value may be released before you can use the packaged result). The P format packages a pointer to a structure that is specified by count. If the corresponding p or P value is undef, a null pointer is created.

The/character allows you to package or unpack such a string: The package structure contains a number of bytes and follows the string itself. You can write length-item/string-item like this. Length-item can be any pack template character and describe how the length value is packaged. The most commonly used items are those that are packaged in integers, such as n (for packaging Java Strings), W (for packaging ASN.1 or SNMP), and N (for Sun XDR). String-item must now be a*,a*, or z*. For unpack, the length of the string is obtained from the Length-item, but if you put it in, it will be ignored.
Unpack ' c/a ', "\04gurusamy"; # Generate ' Guru '
Uppack ' a3/a* A * ', ' 077 Bond J '; # Generate (' Bond ', ' J ')
Pack ' n/a* w/a* ', ' hell ', ', ' world '; # generate "Hello, World"

Length-item does not return explicitly from unpack. Adding a count to the Length-item letter does not necessarily do anything useful unless the letter is A,a, or Z. Packaging with a or Z with Length-item may introduce an empty (in) character, at which point Perl will consider it not a legitimate digital string.

The integer format s,s,l, and L can be followed immediately by one!, which represents the local short integer or long integer, rather than the respective exact 16-bit and 32-bit. Now, this is a problem on many 64-bit platforms on which the local C compiler sees native short integers and long integers that may differ from the above values. (i! and i! can also be used, but only to remain intact; )

You can get the actual length of the native Short,int,long and long long on your Perl platform by using the Config module:
Use Config;
Print $Config {shortsize}, "\ n";
Print $Config {intsize}, "\ n";
Print $Config {longsize}, "\ n";
Print $Config {longlongsize}, "\ n";

It's just that Configure knows the size of a long long, but it doesn't mean you can use Q and Q. (Some systems can have one, but the system you use is probably not yet.) )

Integer formats that are longer than one byte (s,s,i,i,l, and L) are inherently not portable between different processors because they conform to the rules of native byte order and bit weight ordering. If you need a portable integer, use the format n,n, V, and V, because they are byte-weighted and are dimension-aware.

Floating-point numbers exist only in native format. Because the floating-point format is very diverse and lacks a standard "network" representation, there is no tool for floating-point exchange. This means that floating-point data that is packaged on a single machine may not be readable on another platform. Even if both machines are using the IEEE floating-point algorithm, this is still a problem because the memory representation associated with weights is not part of the IEEE specification.

Perl uses double-precision numbers internally for all floating-point calculations, so converting from double to float and then to float will lose precision. This means that unpack ("F", Pack ("F", $foo)) may not be equal to $foo.

It is your responsibility to consider any alignment or padding issues for other programs, especially those with C structs with their own heterogeneous concepts, and the C compiler has a huge difference in how C structs are laid out on different architectures. You may need to add enough x to the package to compensate for this problem. For example, a C declaration:
struct Foo {
unsigned char c;
float F;
};

Can be written as a "C X F" format, a "C X3 F" format, or even an "F C" format--and that's just a part of it. The pack and unpack functions treat their inputs and outputs as a flat byte sequence because they do not know where to go or where to come from.

Let's look at some examples, and the first part of the following wraps the numeric values into bytes:
$out = Pack "CCCC", 65, 66, 67, 68; # $out equals "ABCD"
$out = Pack "C4", 65, 66, 67, 68; # the same thing

The following is the same thing for the Unicode circular letters:
$foo = Pack ("U4", 0x24b6, 0x24b7, 0x24b8, 0x24b9);

The following do something similar, adding some empty:
$out = Pack "CCXXCC", 65, 66, 67, 68; # $out equals "AB\0\0CD"

Packing your short integers does not mean you can migrate:
$out = Pack "S2", 1, 2; # on the front of the machine is the "\1\0\2\0"
# on the front of the machine is "\0\1\0\2"

On binary and hex wrappers, count refers to the number of bits or half bytes, not the number of bytes generated:
$out = Pack "B32", "... (slightly) ";
$out = Pack "H8", "5065726c"; # all generate "Perl"

The length in a field applies only to one string:
$out = Pack "A4", "ABCD", "X", "Y", "Z"; # "ABCD"

To bypass this restriction, use multiple-fold declarations:
$out = Pack "AAAA", "ABCD", "X", "Y", "Z"; # "AXYZ"
$out = Pack "A" x 4, "ABCD", "X", "Y", "Z"; # "AXYZ"

A-format short padding:
$out = Pack "A14", "ABCDEFG"; # "Abcdefg\0\0\0\0\0\0"

This template packs a C's struct TM record (at least on some systems):
$out = Pack "I9PL", Gmtime (), $tz, $toff;

In general, the same template can also be used in the unpack function, although some templates do not have the same action, especially A,a, and Z.

If you want to connect fixed-length text fields together, you can use a TEMPLATE that is multiple packs of a or a:
$string = Pack ("A10" x, @data);

If you want to concatenate a long text field with a delimiter, you can use the Join function:
$string = Join ("and", @data);
$string = Join ("", @data); # empty Separators

Although all of our examples use text strings for templates, there's no reason why you won't be allowed to use templates from disk files. You can make a complete relational database based on this function. (We don't want to know what it's like to prove something to you.) )

PHP Pack && Unpack functions

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.