一、背景介绍
前些天向微信小程序社区提了一个问题:
《扫码接口wx.scanCode识别CODE128/GS1-128码制扫码结果内容缺失?》
因为同一个问题从最早的提问记录看,到现在将近5年了,这个问题一直没有解决,但也看到了提问者没把问题和需求讲明白,这两天把该问题复现及研究了下解决办法,故我尝试把该问题写明白一些。
重要程度:我汇总了一下同一个问题,上万人浏览,说明上万人遇到了同一个问题
2020-11-24,6358浏览,《扫条形码能不能扫GS1格式的特殊符?》https://developers.weixin.qq.com/community/develop/doc/000c28e46a8860b4d44bf173351400?highline=gs1
2021-03-26,2412浏览,《微信扫GS1条形码没有FNC字符?》https://developers.weixin.qq.com/community/develop/doc/0000041a90c5e8f866ebddbbf51000?highLine=gs1
2022-09-20,4518浏览,《GS1-128一维条码,识别结果缺少分隔符?》https://developers.weixin.qq.com/community/develop/doc/0002ae2cc709c8f71e9eab5ca51800
2024-03-04,1054浏览,《现在的微信小程序是否支持医疗机构的GS1条码格式扫描?》https://developers.weixin.qq.com/community/develop/doc/00048a9e500438aec02154c6a61400?highline=gs1
2024-08-30,1751浏览,《小程序调用wx.scanCode去扫码二维码没问题,一维条码返回结果中特殊字符为什么被过滤掉了?》https://developers.weixin.qq.com/community/develop/doc/000c2a04864b0862e102df3ae6d800
条码示例:
小程序扫码结果内容如下:
result: 1727080110FB0726001213818
rawData: MTcyNzA4MDExMEZCMDcyNjAwMTIxMzgxOA==
scanType: CODE_128
rawData转ArrayBuffer: [49,55,50,55,48,56,48,49,49,48,70,66,48,55,50,54,48,48,49,50,49,51,56,49,56]
二、存在的问题:
首先,需要解读CODE128码制规则
如下图百科code128:
其次,我使用原生android的zxing去扫码的结果如下
原文可见内容:1727080110FB0726001213818
原始数据rawData:[ 105, 102, 17, 27, 8, 1, 10, 100, 38, 34, 99, 7, 26, 0, 100, 17, 99, 102, 21, 38, 18, 65, 106 ]
我们拿着对照表(https://www.cnblogs.com/wdxqiang/p/18547839)对照一下这个条码有哪些控制符
对照后,原文对应为:StartC FNC1 1727080110FB0726001 FNC1 213818 Stop
(注意:213818后面Stop前面还有个65,不知道是不是要输出SOH?有专业大佬懂的话回复告知一下)
那么FNC1是什么鬼?网上找的解释如下:
文章地址:https://www.tiaomaruanjian.com/news/6/show-15175.html FNC1起的作用就是区分GS1可变长度的AI(应用标识符)和其他AI,是用ASCII的GS(Group Separator,组分隔符)字符001D=29来表示。 (其中,也有对此处的FNC1起的作用,叫做域分隔符(Field Separator))
FNC1的总结:本身是Code 128等字符集中的一个特殊字符,本身就不属于ASCII字符集,也就不是ASCII中的某个字符。FNC1放在GS1-128字符集中的作用呢,主要就是两个:
1.放在最开始:即放在Start字符后,处于符号集中的第二个位置,在数据之前。此处的作用是,标识此符号集是GS1-128字符集(之前被称为UCC/EAN-128)。
2.放在后面某个位置:即数据中间有FNC1的话,解码器就知道此FNC1是用于区分可变长度的AI(应用标识符)和其他AI,然后就会将其替换为GS字符,然后同条形码的数据一起输出。
经过解读FNC1的作用,那么扫码内容应返回:1727080110FB0726001[GS]213818 或1727080110FB0726001\u001D213818,
即21前面应该有个分隔符,result应该转义出这个分隔符[GS]或\u001D
下图是CODE128编码对照表
最后,总结需求
result: 当遇到code128码制时能够转义不可见的分隔符为可见字符[GS]或\u001D,
rawData: 需要返回必要的控制符和特殊字符,不然这个条码只能观看却无法让第三方应用软件使用。
补充:
微信小程序的扫一扫接口wx.scanCode不支持识别不可见分隔符,那么使用android的zxing去实现扫一扫可以对扫码结果的字节数组rawData二次加工处理识别出分隔符,后来发现zxing有个参数支持gs1-128规则,扫码结果直接回得到分隔符:
com.google.zxing.DecodeHintType.ASSUME_GS1
具体在哪个位置传入需要根据自己的代码来传,网上搜到类似一个例子: