← PHP addslashes()函数:转义引号与反斜杠的指南 PHP chop()函数:从字符串右端移除空白与指定字符教程 →

PHP bin2hex()函数:字符串与十六进制互转教程

著
原创 2026-10-10 PHP 已有人查阅

一、bin2hex()的转换逻辑

bin2hex()做一件事:把字符串中每个字节按十六进制表示出来,返回一个只含0-9和a-f的字符串。

语法:

string bin2hex ( string $str )

参数$str为必填,传入待转换的字符串。返回值为十六进制字符串,长度是原字符串字节数的两倍。

这里要区分一个概念:bin2hex()处理的是字节,不是字符。对ASCII字符来说,一个字符就是一个字节,转换结果直观。但对UTF-8中文、emoji等多字节字符,每个字符会展开成多个字节的十六进制,结果长度不等于字符数乘以2。这是很多初学者第一次接触时容易误解的地方。

核心关键词:PHPbin2hex、字符串转十六进制、ASCII转hex、二进制转十六进制。

二、基础示例:ASCII字符串转换

代码号学习编程建议先跑一个最简单的例子,观察输入与输出的对应关系。

<?php
$str = "Hello World!";
echo "原始字符串:" . $str;
echo "<br>";
echo "bin2hex 结果:" . bin2hex($str);
?>

输出:

原始字符串:Hello World!
bin2hex 结果:48656c6c6f20576f726c6421

拆开看对照关系:

字符 ASCII码(十进制) 十六进制
H 72 48
e 101 65
l 108 6c
o 111 6f
空格 32 20
W 87 57

48656c6c6f20576f726c6421拼起来就是48656c6c6f20576f726c6421。转换过程本质是逐字节的进制映射,没有加密含义,也不涉及压缩。

三、还原转换:pack()与hex2bin()

bin2hex()的逆操作有两条路。

方式一:pack("H*",$hex)

<?php
$str = "Hello world!";
$hex = bin2hex($str);
echo "十六进制值:" . $hex . "<br>";
echo "pack 还原:" . pack("H*", $hex);
?>

输出:

十六进制值:48656c6c6f20776f726c6421
pack 还原:Hello world!

pack("H*",...)中的H表示高四位优先的十六进制,*表示读取到字符串末尾。

方式二:hex2bin()

PHP5.4之后提供了更直接的hex2bin():

<?php
$hex = bin2hex("代码号学习编程");
echo "hex:" . $hex . "<br>";
echo "hex2bin 还原:" . hex2bin($hex);
?>

输出:

hex:e4bba3e7a081e58fb7e5ada6e4b9a0e7bc96e7a88b
hex2bin 还原:代码号学习编程

注意中文的输出:代码号学习编程是7个汉字,UTF-8下每个汉字3字节,共21字节,所以hex字符串长度是42。如果用strlen($hex)/2去推算字符数,会得到21,而不是7。这一点在写长度校验逻辑时必须留意。

个人建议:新项目还原十六进制字符串优先用hex2bin(),语义清晰,比pack("H*")更直观。pack()更适合处理混合格式的二进制打包场景。

四、二进制字符串转十六进制:bindec()+dechex()

bin2hex()处理的是字符串字节,而bindec()处理的是二进制数字字符串。两者容易混淆,但用途不同。

<?php
$binary = "11111001";
echo "二进制值:" . $binary . "<br>";
$hex = dechex(bindec($binary));
echo "转换为十六进制:" . $hex;
?>

输出:

二进制值:11111001
转换为十六进制:f9

拆解过程:

  1. bindec("11111001")把二进制字符串转为十进制整数,结果是249。

  2. dechex(249)把十进制整数转为十六进制字符串,结果是f9。

这条链路适合处理数值型二进制,比如权限位、标志位、协议字段。而bin2hex()适合处理字节流,比如哈希值、随机字节、加密结果的可读化。

对比表:

函数 输入类型 输出 典型场景
bin2hex() 字符串(字节流) 十六进制字符串 哈希展示、token编码
bindec() 二进制数字字符串 十进制整数 位运算、权限解析
dechex() 十进制整数 十六进制字符串 数值格式化

踩坑经历:曾在一个设备通信项目里,把二进制协议字段当成字节流丢给bin2hex(),结果输出不对。后来才意识到协议里给的是二进制数字字符串"1010",应该走bindec()+dechex()。先判断数据是"字节流"还是"数值字符串",再选函数,这个判断顺序能省下不少调试时间。

五、项目场景

场景一:生成随机token的可读形式

<?php
$bytes = random_bytes(8);
$token = bin2hex($bytes);
echo "Token:" . $token;
?>

random_bytes()返回二进制字节,直接输出会乱码,用bin2hex()转成可打印字符串后,便于存入数据库或放入URL。这是bin2hex()在现在PHP中最常见的用法之一。

场景二:哈希值的十六进制展示

<?php
$data = "代码号学习编程";
echo "SHA-1:" . bin2hex(sha1($data, true));
echo "<br>";
echo "MD5:" . bin2hex(md5($data, true));
?>

sha1()和md5()的第二个参数设为true时返回原始二进制,再用bin2hex()转成常见的十六进制形式。如果第二个参数用默认的false,函数本身就会返回十六进制字符串,不需要再套bin2hex()。这里容易多此一举,写代码前先查一下函数签名。

场景三:调试二进制数据

处理图像、压缩包、加密数据时,直接打印二进制会污染终端。用bin2hex()转一下,能安全地观察字节分布。

六、本节课程知识要点

  1. bin2hex()按字节转换,返回长度为原字节数两倍的十六进制字符串。

  2. 多字节字符(中文、emoji)转换后长度不等于字符数乘以2。

  3. 还原优先用hex2bin(),pack("H*")适合混合二进制打包场景。

  4. bindec()+dechex()处理的是数值型二进制字符串,与bin2hex()用途不同。

  5. 生成随机token、展示哈希值时,bin2hex()是常用手段。

  6. 使用md5()/sha1()时注意第二个参数,避免重复转hex。

七、常见问题

Q:bin2hex()能用来加密吗?

A:不能。它只是进制转换,没有密钥,任何人拿到hex字符串都能还原。加密需要用openssl_encrypt()、sodium_crypto等专用函数。

Q:bin2hex()和dechex()有什么区别?

A:bin2hex()输入是字符串,逐字节转hex;dechex()输入是十进制整数,输出该整数的十六进制表示。前者处理字节流,后者处理数值。

Q:hex2bin()报错"Hexadecimalinputstringmusthaveanevenlength"怎么处理?

A:十六进制字符串长度必须是偶数,每两个字符代表一个字节。检查来源数据是否被截断,或补零对齐。

bin2hex()是PHP中处理字节流与十六进制字符串互转的基础函数,逻辑直白但边界需要注意:它按字节工作,不按字符;它不做加密,只做表示形式的转换。配合hex2bin()、random_bytes()、hash函数使用,能覆盖token生成、哈希展示、二进制调试等常见需求。遇到二进制数字字符串时,先分清是"字节流"还是"数值",再决定用bin2hex()还是bindec()+dechex(),这个判断习惯比记住函数名更有价值。

← PHP addslashes()函数:转义引号与反斜杠的指南 PHP chop()函数:从字符串右端移除空白与指定字符教程 →
分享笔记 (共有 篇笔记)
验证码:
微信公众号