bin2hex()是php中最快最安全的字符串转十六进制方法,按字节原样转换为两位十六进制字符,支持utf-8等任意编码,性能优于unpack("h*"),配套hex2bin()可逆转换。

用 bin2hex() 最快把字符串转十六进制
PHP 里把字符串转成十六进制,bin2hex() 是最直接、最安全的选择。它把每个字节原样转成两位十六进制字符,不编码、不解释字符集,纯二进制视角处理。
常见错误是拿 dechex() 或自己写循环 —— 那只适合转单个数字,对字符串完全无效,会报 Warning: dechex() expects parameter 1 to be int。
使用场景包括生成 token 前缀、调试二进制协议、构造 HTTP 头原始值等,只要你要的是「字节 → hex 字符串」映射,就该用它。
-
bin2hex("abc")→"616263"(a=0x61, b=0x62, c=0x63) - 输入是 UTF-8 字符串也没问题,比如
bin2hex("中文")→"e4b8ade69687",但要注意这是按 UTF-8 编码后的字节转的,不是 Unicode 码点 - 空字符串
bin2hex("")返回"",不会报错
别用 unpack("H*", $str) 替代 bin2hex()
unpack("H*", $str) 确实也能出 hex 字符串,但它是为结构化解包设计的,性能差、语义重、还容易踩坑。
立即学习“PHP免费学习笔记(深入)”;
典型问题是:返回的是数组,不是字符串 —— unpack("H*", "ab") 得到 ["6162"],你得再取 [0];更麻烦的是,如果字符串长度是奇数(比如 "a"),unpack("H*") 会截断末尾字节,静默丢数据,而 bin2hex() 没这问题。
-
bin2hex("a")→"61"(正确) -
unpack("H*", "a")[0]→"61"(碰巧对,但不可靠) -
unpack("H*", "\x00\x01\x02")[0]→"000102"(看起来一样,但底层多一层解析开销) - 在循环里高频调用时,
bin2hex()比unpack()快 3–5 倍(PHP 8.1+ 实测)
十六进制字符串转回字符串用 hex2bin()
和 bin2hex() 配套的是 hex2bin(),不是 pack("H*", $hex)。后者在 PHP 8.2+ 已标记为“不推荐”,且对非法 hex 字符(如空格、字母大小写混用)容忍度低,会直接警告并返回 false。
hex2bin() 更严格也更可靠:只接受偶数长度、全为 [0-9a-fA-F] 的字符串;遇到非法输入立刻报 ValueError(PHP 8.0+)或警告(旧版),不默默截断。
-
hex2bin("616263")→"abc" -
hex2bin("616")→ 报错(长度奇数) -
hex2bin("61g2")→ 报错(含非法字符g) - 如果必须容错,先用
preg_replace("/[^0-9a-fA-F]/", "", $hex)清洗,再确保长度为偶数,最后调hex2bin()
注意 mbstring 扩展没提供字符串进制转换函数
有人搜 “php 多字节字符串转 hex”,以为 mb_convert_encoding() 或 mb_detect_encoding() 能干这事 —— 它们完全不涉及进制转换,只管字符编码转换。想处理 GBK/UTF-16 字符串?先用 mb_convert_encoding($str, "UTF-8", $source_encoding) 统一转成 UTF-8,再喂给 bin2hex()。
另一个常见误解是认为 base64_encode() 是十六进制 —— 它是 Base64,字符集不同(A-Z a-z 0-9 + /),不能混用。Hex 是固定 0–9 a–f,长度恒为原文本字节数 × 2。
- UTF-16 字符串(如 Windows 记事本默认保存)含 BOM 和双字节,
bin2hex(file_get_contents("utf16.txt"))结果开头是"fffe",这就是 BOM,别当成乱码删掉 - 用
file_get_contents()读文件时,默认是二进制模式,正好适配bin2hex(),不用额外设置











