二进制,十进制,十六进制之间的转换
bindec 二进制转十进制
decbin 十进制转二进制
hexdec 十六进制转十进制
dechec 十进制转十六进制二进制转十六进制
dechex(bindec("1110")) // e 十六进制转二进制
decbin(hexdec("f")) // 1111 base_convert(string $number, int $frombase, int $tobase) 任意进制之间的转换
base_convert("11111111", 2, 16); // ff十进制转十六进制
sprintf("%08x", 10); // a
sprintf("%08x", -10); // fffffff6
特别注意
负数的二进制是采用的补码,而这个补码并不是这个负数本身。
dechex("10"); // a
hexdec("a"); // 10dechex("-10"); // fffffff6
hexdec("fffffff6"); // 4294967286decbin("10"); // 1010
bindec("1010"); // 10decbin("-10"); // 11111111111111111111111111110110
bindec("11111111111111111111111111110110"); // 4294967286
所以,可以看到,将一个负数转成二进制或者十六进制,然后再赚回来就不对了,因为本质上,一个二进制并不存在正负之分,需要区分的是在应用层面,所以通过其他方式来标记这个数为正数还是负数,如果为负数的话则需要参考补码的方式在使其还原成原码。
另外,有一个极度误解的函数
bin2hex(string
$str
): string函数把包含数据的二进制字符串转换为十六进制值
它会将传入的参数转换成字符串,然后将逐个字符的ASCII码转换成十六进制。
$a = 0b1111;
$b = "ab";
$c = 10;
$d = "1110";// 0b1111 的值是15,对应的字符串是“15”,对应的ASCII为49和53,对应的十六进制为31和35
echo bin2hex($a), PHP_EOL; // 3135
echo bin2hex($b), PHP_EOL; // 6162
echo bin2hex($c), PHP_EOL; // 3130
echo bin2hex($d), PHP_EOL; // 31313130
所以说 bin2hex
不是二进制转十六进制。它的真实作用是将字符串按逐个字符转换成二进制,然后逐个的将单个字节转换成十六进制。本质上并没有改变值,只是换了一个表示方式。
bin2hex("中"); // e4b8ad
hex2bin("e68891"); // 中
而hex2bin
则刚好相反。
这个在字符串加密的时候挺有用的。比如:
echo bin2hex("我"), PHP_EOL; // e68891
$s = pack("H6", bin2hex("我"));
$s1 = unpack("H6", $s);
var_dump(hex2bin($s1[1]));
二进制的每四位构成的最大值为15,正好是一个十六进制的最大值F,所以说一个字节会变成两个十六进制的字符,对应的是两个字节,占用空间扩大一倍。另外十六进制的A-F也不区分大小写。十六进制的作用是方便人来阅读和展示,比十进制更直观。
计算机在展示二进制数据到屏幕的时候可读性很差,会有很多不可见的字符和乱码,因此,很多场合都会转换成十六进制,比如md5,base64。