在实践中用到一些进制转换函数,现将部分函数使用方法总结如下:
其中,常说的16进制字符串指的是,0-9A-Fa-f的ASCII码字符串。
hexdec
(PHP 4, PHP 5, PHP 7)
hexdec ( string $hex_string
) : number
返回与 hex_string
参数所表示的十六进制数等值的的十进制数。hexdec() 将一个十六进制字符串转换为十进制数。它会忽略它遇到的任意非十六进制的字符。
dechex
(PHP 4, PHP 5, PHP 7)
dechex — 十进制转换为十六进制
dechex ( int $number
) : string
返回一字符串,包含有给定 number
参数的十六进制表示。
所能转换的最大数值为十进制的 PHP_INT_MAX
* 2 + 1 (或 -1):在 32 位平台上是十进制的 4294967295,其 dechex() 的结果为 ffffffff。
decbin
(PHP 4, PHP 5, PHP 7)
decbin — 十进制转换为二进制
decbin ( int $number
) : string
返回一字符串,包含有给定 number
参数的二进制表示。所能转换的最大数值为十进制的 4294967295,其结果为 32 个 1 的字符串。
decoct
(PHP 4, PHP 5, PHP 7)
decoct — 十进制转换为八进制
decoct ( int $number
) : string
返回一字符串,包含有给定 number
参数的八进制表示。所能转换的最大数值为十进制的 4294967295,其结果为 "37777777777"。
base_convert
(PHP 4, PHP 5, PHP 7)
base_convert — 在任意进制之间转换数字
base_convert ( string $number
, int $frombase
, int $tobase
) : string
返回一字符串,包含 number
以 tobase
进制的表示。number
本身的进制由 frombase
指定。frombase
和 tobase
都只能在 2 和 36 之间(包括 2 和 36)。高于十进制的数字用字母 a-z 表示,例如 a 表示 10,b 表示 11 以及 z 表示 35。
Warning 由于使用内部的 "double" 或 "float" 类型,base_convert() 的操作可能会导致大数值中的精度丢失。请参见本手册的 浮点数 章节以便获得更多详细信息。
str_pad
(PHP 4 >= 4.0.1, PHP 5, PHP 7)
str_pad — 使用另一个字符串填充字符串为指定长度
str_pad ( string $input
, int $pad_length
[, string $pad_string
= " " [, int $pad_type
= STR_PAD_RIGHT ]] ) : string
该函数返回 input
被从左端、右端或者同时两端被填充到制定长度$pad_length
后的结果。可选的 pad_type
参数的可能值为STR_PAD_RIGHT
,STR_PAD_LEFT
或 STR_PAD_BOTH。
例子,将一个16进制字符串$hex,从左至右,按字节两两异或,就最后的结果。
public static function lrc_trans($string)
{
$LRC = 0;
$arr = str_split($string, 2); //2个十六进制数,为一个八位字节,str_split按指定长度分割
foreach ($arr as $char) {
$LRC ^= base_convert($char, 16, 10);
}
return str_pad(base_convert($LRC, 10, 16), 2, '0', STR_PAD_LEFT); //复原十六进制数,即2个
}
chr
(PHP 4, PHP 5, PHP 7)
chr — 返回指定的字符
将十六进制字符串转换为预定义的字符,
chr(hexdec($hex));
pack
(PHP 4, PHP 5, PHP 7)
pack — 将数据打包成二进制字符串
pack ( string $format
[, mixed $args
[, mixed $...
]] ) : string
根据format
将给地的参数打包成二进制字符串。
format
字符串由格式代码组成,后面跟着一个可选的重复参数。 重复参数可以是一个整数值或者*值来重复到输入数据的末尾。对于a, A, h, H格式化代码,其后的重复参数指定了给定数据将会被使用几个字符串,对于@,其后的数字表示放置剩余数据的绝对定位(之前的数据将会被空字符串填充),对于其他所有内容,重复数量指定消耗多少数据并将其打包到生成的二进制字符串中。
代码 | 描述 |
---|---|
a | 以NUL字节填充字符串 |
A | 以SPACE(空格)填充字符串 |
h | 十六进制字符串,低位在前 |
H | 十六进制字符串,高位在前 |
c | 有符号字符 |
C | 无符号字符 |
s | 有符号短整型(16位,主机字节序) |
S | 无符号短整型(16位,主机字节序) |
n | 无符号短整型(16位,大端字节序),高位在前 |
v | 无符号短整型(16位,小端字节序),高位在后 |
i | 有符号整型(机器相关大小字节序) |
I | 无符号整型(机器相关大小字节序) |
l | 有符号长整型(32位,主机字节序) |
L | 无符号长整型(32位,主机字节序) |
N | 无符号长整型(32位,大端字节序) |
V | 无符号长整型(32位,小端字节序) |
q | 有符号长长整型(64位,主机字节序) |
Q | 无符号长长整型(64位,主机字节序) |
J | 无符号长长整型(64位,大端字节序) |
P | 无符号长长整型(64位,小端字节序) |
f | 单精度浮点型(机器相关大小) |
g | 单精度浮点型(机器相关大小,小端字节序) |
G | 单精度浮点型(机器相关大小,大端字节序) |
d | 双精度浮点型(机器相关大小) |
e | 双精度浮点型(机器相关大小,小端字节序) |
E | 双精度浮点型(机器相关大小,大端字节序) |
x | NUL字节 |
X | 回退已字节 |
Z | 以NUL字节填充字符串空白(PHP 5.5中新加入的) |
@ | NUL填充到绝对位置 |
args 为指定格式的数
理解:
echo pack("v*", '41'); ------ 输出),“v*”表示参数是十进制,即结果为ASCII码值41的符号")"。
echo pack("H*", '41'); ------ 输出A,“H*”表示参数是十六进制即0x41(十进制数65),即结果为ASCII码值65的字符"A"。
echo pack("c*", '41'); ------ 输出),“c*”表示参数是十进制,即结果为ASCII码值41的符号")"。
echo bin2hex(pack("H*", '41')); ------ 输出41,“H*”表示参数是十六进制即0x41,即结果输出十六进制字符串“41”。
echo bin2hex(pack("v*", '4')); ------ 输出0400
echo bin2hex(pack("v*", '1')); ------ 输出0100
echo bin2hex(pack("v*", '41')); ------ 输出2900,“v*”表示参数是十进制,内存中保存为0x2900(16位,即2个字节),所以结果为“2900”。
总结,pack函数返回字符,其中格式指定了参数是十进制还是十六进制数,将参数转换为16进制数(结果的保存内容),再结合格式指定的保存位数,最终确定结果在内存中的保存形式。而bin2hex可以直接输出该数再内存中的保存样式。
unpack
(PHP 4, PHP 5, PHP 7)
unpack — Unpack data from binary string
说明
unpack ( string $format
, string $data
[, int $offset
= 0 ] ) : array
<?php
$binarydata = "\x04\x00\xa0\x00";
$array = unpack("cchars/nint", $binarydata);
print_r($array);
?>
输出:
Array
(
[chars] => 4 # "\x04"
[int] => 160 # "\x00\xa0"
)
<?php
$binarydata = "\x04\x00\xa0\x00";
$array = unpack("c2chars/nint", $binarydata);
print_r($array);
?>
输出:
Array
(
[chars1] => 4 # "\x04"
[chars2] => 0 # "\x00"
[int] => 40960 # "\xa0\x00", 即0xA00 = 10*16*16*16 = 40960, ‘n’表示高位在前,‘v’表示高位在后
)
<?php
// example code
function parse_machine_error_code($hex_bytes, $reverse = false)
{
$n = strlen($hex_bytes)/2;
$bin_bytes = '';
if (!is_int($n)) {
throw new \InvalidArgumentException('Invalid Hexadecimal Byte String');
}
for ($i=0; $i<$n; $i++) {
$byte = substr($hex_bytes, 2*$i, 2);
$bin_byte = str_pad(base_convert($byte, 16, 2), 8, '0', STR_PAD_LEFT);
$bin_bytes = $reverse ? $bin_byte.$bin_bytes : $bin_bytes.$bin_byte;
}
$err_codes = array_map(function($value){
return $value + 1;
}, array_keys(array_filter(array_reverse(str_split($bin_bytes)))));
return $err_codes;
}
var_dump(parse_machine_erro_code('010000', true));