问题: XcxYY202607201734190a99 这个字符串,用 js 的 qrcode.min.js 生成的二维码,用微信扫出的结果是一样的,但是用扫码枪和扫码盒子扫出的是 XcxYY2607201734190a99,居然少中间的 20 两个字符。
一、为什么会少 20 变成 260720?
核心原因:扫码设备(扫码枪 / 扫码盒)开启了日期年份自动压缩 / 两位年份优化功能
你的原文:XcxYY202607201734190a99
中间片段 2026 → 扫码设备内置规则识别为四位公历年份,自动裁剪前两位 20,解析成两位年份 26
解析后字符串:XcxYY2607201734190a99,正好丢失 20。
区分设备行为:
微信内置扫码:纯文本读取,不做字符智能解析、不裁剪年份;
工业扫码枪 / 收银扫码盒:默认开启条码智能格式化,会自动识别日期、手机号、数字段做精简处理,这是硬件固件自带逻辑,无法直接关闭时只能改二维码内容格式。
补充诱因
你的编码片段 20260720 是标准 YYYYMMDD 日期格式,几乎所有扫码设备都会命中年份缩写规则。
二、有时候XcxYY这些的字符也会变为汉字
解决办法:
1、字母后面加 - 字符,就不转换为汉字了
2、时间不要用年月日时分秒,改成用时间戳的
3、字母后面的8数字开头是因为时间戳1开头,这个1扫码盒子读不出来
4、后面的4位随机字符串必须都是数字,否则扫码盒子会读出中文来
$outTradeNo = 'XcxYY-8'.time().onceNumstr(4);
function onceNumstr($length = 32, $str = "")
{
$chars = "0123456789";
for ($i = 0; $i < $length; $i++) {
$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
}
return $str;
}