I'm having a little trouble understanding Perl's unpack in some code I'm reading, specifically with the S*
template.
$data = "FF";
print "$data - ", unpack("S*", $data), "\n";
# > FF - 17990
Thanks very much for your help
Your code in C would look (roughly) like this:
const char *data = "FA";
unsigned short s;
memcpy( &s, data, strlen(data) );
printf("%s = %d\n", data, s);
This only handles your case with two characters, while unpack('S*',...) will return a list of shorts corresponding to its input.
Why? One of the primary motivations for pack and unpack was to make it easier interchange binary data with C structures.
perlpacktut is a good place to start.
unpack 'S'
casts two bytes into a uint16_t
.
#include <stdint.h>
const char *data = "\x46\x41";
uint16_t n;
memcpy(&n, data, sizeof(n)); // n = 0x4146 or 0x4641
Don't forget to check the number of bytes in data
before doing this!
Notice that it can give two different results based on the system.
On a little-endian system (e.g. x86, x64), unpack 'S'
is also equivalent to
uint16_t n = (data[1] << 8) | data[0]; // 0x4146
On a big-endian system, unpack 'S'
is also equivalent to
uint16_t n = (data[0] << 8) | data[1]; // 0x4641
By the way, you might be tempted to do the following, but it's not portable due to memory alignment issues:
uint16_t n = *((const uint16_t *)data);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With