Core Function Pack

From Sputnik Wiki
(Difference between revisions)
Jump to: navigation, search
(Return Value)
(Control Specifiers)
Line 42: Line 42:
 
==== Control Specifiers ====
 
==== Control Specifiers ====
  
{| border="1" align="left" style="text-align:center;"
+
<pre>
|Character
+
Character Description
|Description
+
^ Switch to big endian encoding
|-
+
_ Switch to little endian encoding
|^
+
% Switch to host (native) encoding
|Switch to big endian 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
|Switch to little endian encoding
+
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
|Switch to host (native) encoding
+
[N] For numbers larger than 9, use brackets, for example [20]
|-
+
* Repeat the next data type until the arguments are exhausted  
|!
+
<pre>
|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 ====
 
==== Data Encoding ====

Revision as of 14:11, 8 September 2013

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 
<pre>

==== 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.

{| border="1" align="left" style="text-align:center;"
|Character
|Description
|-
|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
|-
|h
|Hex string to convert to bytes (For Pack)
|-
|h
|2 Char Lowercase Hexstring of a byte (For Unpack)
|-
|H
|2 Char Uppercase Hexstring of a byte (For Unpack)
|-
|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 terminator
|-
|$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
|-
|x
|null byte
|}



































































=== Example ===

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

<syntaxhighlight lang="sputnik">
$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);
</syntaxhighlight>

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

<syntaxhighlight lang="sputnik">
$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 );
}
</syntaxhighlight>

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

<syntaxhighlight lang="sputnik">
$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 );
}
</syntaxhighlight>

Convert a string into a binary array and back again:

<syntaxhighlight lang="sputnik">
$arr = Pack("z0", "Hello World!");
foreach ($arr as $i)
{
	println($i);
}
$str = Unpack("z0", $arr);
println($str);
</syntaxhighlight>

Convert a dobule into a binary array and back again:
<syntaxhighlight lang="sputnik">
$arr = Pack("d", 777.42);
foreach ($arr as $i)
{
	println($i);
}
$str = Unpack("d", $arr);
println($str);
</syntaxhighlight>

Convert a int into a binary array and back again:
<syntaxhighlight lang="sputnik">
$arr = Pack("d", (int)777);
foreach ($arr as $i)
{
	println($i);
}
$str = Unpack("d", $arr);
println($str);
</syntaxhighlight>

Convert a string into a hex and back again:
<syntaxhighlight lang="sputnik">
$hex = Join(Unpack("*H", Pack("z0", "Hello World!")), '');
println("Hex String: " . $hex);
$str = Unpack("z0", Pack("h", $hex));
println("Normal String: " . $str);
</syntaxhighlight>

Convert a string into a hex and back again (alternative 1):
<syntaxhighlight lang="sputnik">
$hex = Unpack("*H", "Hello World!", 1);
println("Hex String: " . $hex);
$str = Unpack("z0", Pack("h", $hex));
println("Normal String: " . $str);
</syntaxhighlight>

Convert a string into a hex and back again (alternative 2):
<syntaxhighlight lang="sputnik">
$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);
</syntaxhighlight>


To pack two integers in big endian format, you would use this:
<syntaxhighlight lang="sputnik">
$bytes = Pack ("^ii", 1234, 4542);
</syntaxhighlight>

More Examples:
<syntaxhighlight lang="sputnik">
; 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
</syntaxhighlight>

[[Category:Core Function]]
Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox