Swift如何实现与PHP hex2bin等效的十六进制转字符串及拼接
Swift 实现与 PHP hex2bin 输出对齐的二进制拼接逻辑
为什么之前的Swift实现和PHP结果对不上
PHP 里的字符串根本不是抽象的文本类型,就是一个单纯的原始字节数组容器。hex2bin把十六进制串转成对应的字节,之后和'222'拼接,本质就是把两段字节数组按顺序拼到一起,全程没有任何字符编码转换的介入。
之前的实现错在强行把十六进制转出来的原始字节,通过某个编码转成了Swift的String:
- 哪怕用isoLatin1这类看起来能直接映射单字节的编码,只要遇到编码表外的字节,转换过程就会自动替换成占位符,直接篡改原始字节
- 就算转换侥幸成功,Swift的
String底层是按UTF-8规则存储内存的,后续拼接222的时候,字符串类型的规范化处理还会再篡改一次字节
两头修改之后,最后拼出来的结果自然和PHP的纯字节拼接结果对不上。
正确的实现方式
别绕Swift的String弯子,直接用Data类型完成操作即可——Data本身就是Swift里的原始字节数组类型,和PHP字符串的底层逻辑完全等价:
- 把十六进制串直接转成
Data,这一步得到的字节和PHPhex2bin的结果逐字节对齐,不需要额外做编码转换 - 把要拼接的
"222"也转成Data,因为是纯ASCII字符,转换得到的字节和PHP里'222'的底层存储字节完全一样 - 两个
Data对象直接拼接,得到的最终结果就和PHP的$concatResult输出完全一致
参考实现代码
// 十六进制串转原始字节Data(与PHP hex2bin输出逐字节一致) let hexPart = Data(hex: "c0e11c7d13b7bf84b83bb5c8a7873c1c") // 待拼接的普通字符串转字节Data let stringPart = "222".data(using: .utf8)! // 直接拼接得到与PHP输出完全对齐的结果 let finalResult = hexPart + stringPart
结果对齐验证
把Swift端拼接完成的finalResult转为十六进制字符串输出,和PHP端执行bin2hex($concatResult)得到的十六进制结果做逐字节比对,两边字符串完全一致即代表实现对齐。
避坑提醒:千万别尝试把包含高位字节的原始Data通过任意编码转回Swift的String类型再做拼接,只要经过String类型的中转,不管用什么编码,迟早会因为Swift的Unicode字符串规则破坏原始字节,根本无法匹配PHP的输出结果。
内容的提问来源于stack exchange,提问作者Hossein
相关产品推荐
相关产品推荐

