Core Function Pack

From Sputnik Wiki
Revision as of 14:43, 8 September 2013 by UberFoX (Talk | contribs)
Jump to: navigation, search
Pack( <expression>, <expressions> )

Contents

Description

Pack data into a binary array

expression

The format string to use.

expressions

One or more expressions to convert.

Return Value

Success: Returns a binary variable which contains the array of bytes.

Failure: Returns null.

Remarks

To access the binary data in the variable you will need to either request elements from index id, cycle through all elements in a loop or use the Unpack function to convert the binary array into something useful.

Its worth noting you can cycle through a Binary variable like this :

$binary = Pack("z0", "Hello World!");
Foreach ($binary as $i)
{
	println( "Byte: " . $i . " | Hex: " . Hex($i) . " | Char: " . Chr($i) );
}

Or like this :

$binary = Pack("z0", "Hello World!");
println( "Byte: $i Hex: {Hex('$i')} Char: {Chr('$i')}" ) Foreach ($binary as $i);

Control Specifiers

Character 		Description
^ 			Switch to big endian encoding
_ 			Switch to little endian encoding
% 			Switch to host (native) encoding
! 			Aligns the next data type to its natural
			boundary, for example for a double that
			would be 8 bytes, for a 32-bit int, that
			would be 4 bytes. For strings this is set to 4.
N 			A number between 1 and 9, indicates a repeat count
			(process N items with the following datatype
[N] 			For numbers larger than 9, use brackets, for example [20]
* 			Repeat the next data type until the arguments are exhausted 

Data Encoding

Warning - The pack for $variables is designed to create the bytes of the arrays elements such as array of ints however it does not unpack to a $variable instead you must unpack it as the base type you packed it to such as Int32.

Character 		Description
FOR PACK AND UNPACK BELOW
s 			Int16
S 			UInt16
i 			Int32
I 			UInt32
l 			Int64
L 			UInt64
f 			Float
d 			Double
b 			Byte
c 			1-byte signed character
C 			1-byte unsigned character
vb 			Binary representation of a Byte
vs 			Binary representation of a Int16
vi 			Binary representation of a Int32
vl 			Binary representation of a Int64
vS 			Binary representation of a UInt16
vI 			Binary representation of a UInt32
vL 			Binary representation of a UInt64
vf 			Binary representation of a Float
vd 			Binary representation of a Double
z8 			string encoded as UTF8 with 1-byte null terminator
z6 			string encoded as UTF16 with 2-byte null terminator
z7 			string encoded as UTF7 with 1-byte null terminator
zb 			string encoded as BigEndianUnicode with 2-byte null terminator
z3 			string encoded as UTF32 with 4-byte null terminator
z4 			string encoded as UTF32 big endian with 4-byte null terminator
z0 			ASCII string without a null terminator
z1 			ASCII string with 1-byte null terminator
x 			null byte 

FOR UNPACK ONLY BELOW
h 			2 Char Lowercase Hexstring of a byte 
H 			2 Char Uppercase Hexstring of a byte

FOR PACK ONLY BELOW
h 			Hex string to convert to bytes
$ab 			A $variable containing an array of Byte values
$as 			A $variable containing an array of Int16 values
$aS 			A $variable containing an array of UInt16 values
$ai 			A $variable containing an array of Int32 values
$aI 			A $variable containing an array of UInt32 values
$al 			A $variable containing an array of Int64 values
$aL 			A $variable containing an array of UInt64 values
$af 			A $variable containing an array of Float values
$ad 			A $variable containing an array of Double values

Note - All Sputnik strings are UTF8 by default.

Example

Converting an array of Ints into bytes then back into an array of ints again:

$oldArray = array(100, 200, 300, 400); // Create an array
// Pack the array into bytes with each element converted to Int32
$binary = Pack('$ai', $oldArray); // NOTICE '' was used instead of ""? This is vital when packing variables or else it will fail
Foreach ($binary as $i)
{
	println( "Byte: " . $i ); // Prints the bytes just for looksee
}
$newArray = Unpack('*i', $binary); // Unpack All the Int32s into an array
println("Old Array : " . $oldArray);
println("New Array : " . $newArray);

Same as above but this time packing a float and a double as well :

$oldArray = array(100, 200, 300, 400); // Create an array
// Pack the array into bytes with each element converted to Int32
$binary = Pack('$aifd', $oldArray, (float)777, (double)1337.42); // NOTICE '' was used instead of ""? This is vital when packing variables or else it will fail
Foreach ($binary as $i)
{
	println( "Byte: " . $i ); // Prints the bytes just for looksee
}
$newArray = Unpack('4ifd', $binary); // Unpack 4 Int32s, 1 float and 1 double into an array
println("Old Array : " . $oldArray);
println("New Array : " . $newArray);
foreach ($newArray as $i)
{
	println("Value: " . $i );
}

Of course we could set how many Ints to decode dynamically example:

$oldArray = array(100, 200, 300, 400); // Create an array
// Pack the array into bytes with each element converted to Int32
$binary = Pack('$aifd', $oldArray, (float)777, (double)1337.42); // NOTICE '' was used instead of ""? This is vital when packing variables or else it will fail
Foreach ($binary as $i)
{
	println( "Byte: " . $i ); // Prints the bytes just for looksee
}
$newArray = Unpack(UBound($oldArray) . 'ifd', $binary); // Unpack 4 Int32s, 1 float and 1 double into an array
println("Old Array : " . $oldArray);
println("New Array : " . $newArray);
foreach ($newArray as $i)
{
	println("Value: " . $i );
}

Convert a string into a binary array and back again:

$arr = Pack("z0", "Hello World!");
foreach ($arr as $i)
{
	println($i);
}
$str = Unpack("z0", $arr);
println($str);

Convert a dobule into a binary array and back again:

$arr = Pack("d", 777.42);
foreach ($arr as $i)
{
	println($i);
}
$str = Unpack("d", $arr);
println($str);

Convert a int into a binary array and back again:

$arr = Pack("d", (int)777);
foreach ($arr as $i)
{
	println($i);
}
$str = Unpack("d", $arr);
println($str);

Convert a string into a hex and back again:

$hex = Join(Unpack("*H", Pack("z0", "Hello World!")), '');
println("Hex String: " . $hex);
$str = Unpack("z0", Pack("h", $hex));
println("Normal String: " . $str);

Convert a string into a hex and back again (alternative 1):

$hex = Unpack("*H", "Hello World!", 1);
println("Hex String: " . $hex);
$str = Unpack("z0", Pack("h", $hex));
println("Normal String: " . $str);

Convert a string into a hex and back again (alternative 2):

$hex = Unpack("*H", "Hello World!", 1);
println("Hex String: " . $hex);
$hex =~ s/([\dA-Fa-f][\dA-Fa-f])/Chr(Dec($1))/ego;
println("Normal String: " . $hex);


To pack two integers in big endian format, you would use this:

$bytes = Pack ("^ii", 1234, 4542);

More Examples:

; The following means:
; Little endian encoding of a Int16, followed by an aligned
; int32 value.
$r = Pack("_s!i", 0x7b, 0x12345678);
foreach ($r as $i)
{
	print(Hex($i) . " ");
}
// Prints 7B 0 0 0 80 56 34 12
 
$bytes = Pack("CCCC", 65, 66, 67, 68);
foreach ($bytes as $i)
{
	print(Chr($i) . " ");
} // Prints 4-byte sequence for "ABCD"
 
$bytes = Pack("4C", 65, 66, 67, 68);
foreach ($bytes as $i)
{
	print(Chr($i) . " ");
} // Prints 4-byte sequence for "ABCD"
 
$bytes = Pack("*C", 65, 66, 67, 68);
foreach ($bytes as $i)
{
	print(Chr($i) . " ");
} // Prints 4-byte sequence for "ABCD"
 
$bytes = Pack("^ii", 0x1234abcd, 0x7fadb007);
foreach ($bytes as $i)
{
	print(Hex($i) . " ");
}
println(""); // Result: 12 34 ab cd 7f ad b0 07
 
// Encode 3 integers as big-endian, but only provides two as arguments,
// this defaults to zero for the last value.
$bytes = Pack("^iii", 0x1234abcd, 0x7fadb007);
foreach ($bytes as $i)
{
	print(Hex($i) . " ");
}
println(""); // Result: 12 34 ab cd 7f ad b0 07 00 00 00 00
 
// Encode as little endian, pack 1 short, align, 1 int
$bytes = Pack("_s!i", 0x7b, 0x12345678);
foreach ($bytes as $i)
{
	print(Hex($i) . " ");
}
println(""); // Result: 7b 00 00 00 78 56 34 12
 
// Encode a string in utf-8 with a null terminator
$bytes = Pack("z8", "hello");
foreach ($bytes as $i)
{
	print(Hex($i) . " ");
}
println(""); // Result: 68 65 6c 6c 6f 00 00 00 00
 
// Little endian encoding, for Int16, followed by an aligned
// Int32
$bytes = Pack("_s!i", 0x7b, 0x12345678);
foreach ($bytes as $i)
{
	print(Hex($i) . " ");
}
println(""); // Result: 7b 00 00 00 78 56 34 12
Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox