js生成的二维码扫码枪读出的跟原字符值不一样

字体:

问题: 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;
}