从扫描的GS1类型条形码中提取信息

4
我希望您能从扫描的GS1条形码信息中确定产品信息,例如描述、制造商和过期日期。如何实现?

2
可能是UPC API数据库查找的重复问题。 - Rob Rose
请参考我在此处给出的谷歌提供的对你问题的替代解决方案:http://stackoverflow.com/questions/31889728/getting-actual-data-from-scanned-barcode-in-android/32393928#32393928 - Namrata Bagerwal
3个回答

12

获取由存储在GS1应用标识符标准格式中的GS1类型条形码所代表的信息涉及两个过程。

  1. 提取扫描符号获得的GS1结构化数据中包含的数据字段(称为应用标识符)。这始终包括一个名为GTIN-14的项目唯一标识符,以及可能包括附加信息,例如到期日期、批号等。该过程可以由独立的应用程序执行。
  2. 查找已提取的GTIN在数据库中查询,可以是您的应用程序本地数据库或通过某些公共API,以提供原产国、制造商和可能的物品描述的文本表示方式。为了全面执行此过程,应用程序需要访问外部资源。

背景:GS1应用标识符标准格式组成

GS1格式化数据由应用标识符(AI)和值的连接列表组成,以AI(01)开头,代表GTIN。例如,数据“(01) 95012345678903 (10) 000123 (17) 150801”表示以下信息:

GTIN:             95012345678903
BATCH/LOT:        000123
USE BY OR EXPIRY: 1st August 2015

GS1通用规格说明书的第三节,GS1应用标识符定义提供了每个应用标识符(AI)的含义,并重要地指出了是否根据定义为可变长度固定长度,在后一种情况下,还提供了必需长度。

GS1条形码使用特殊的非数据字符(FNC1)来表明数据符合GS1应用标识符标准格式,并将可变长度数据字段的结尾与下一个AI分隔开。例如,上述数据可以编码为Code 128符号,如{FNC1}019501234567890310000123{FNC1}17150801,以产生以下GS1-128符号:

GS1-128: (01)95012345678903(10)000123(17)150801

当条形码扫描仪读取该符号时,它将被解码如下[†]:

019501234567890310000123{GS}17150801

请注意,初始的FNC1非数据字符已被丢弃,用于可变长度AI分隔符角色的FNC1已由GS字符(ASCII值29)表示。

提取(和可选验证)

您的应用程序可以直接提取GTIN和任何补充信息。

要从条形码扫描仪解码的GS1符号数据中提取原始应用标识符数据,需要您的应用程序包含一个数据结构,我们将其称为AI-TABLE,将AI模式映射到它们的值的长度,这些值是从上述链接的GS1通用规范的部分提供的数据中派生出来的:

AI     | N (value length)
-------------------------
(00)   | 18
(01)   | 14
(10)   | variable
(17)   | 6
(240)  | variable
(310n) | 6
(37)   | variable
...

有了这个工具,您可以按照以下步骤从扫描的条码数据中进行AI价值提取:

while more data:
    AI,N = Entry from AI-TABLE matching a prefix of the data, otherwise FAIL.

    if N is fixed-length:
        VALUE = next N characters
    else N is variable length:
        VALUE = characters until "GS" or end of data
     
    emit: (AI) VALUE
在实践中,你可以选择将更多的数据从 "General Specifications" 中包含在你的 AI-TABLE 中,以允许你的应用程序对每个 VALUE 的类型和长度进行增强验证。但是以上内容已足够提取所需数据,例如代表过期日期的AI(17)。
更新于2022年8月:GS1最近发布了GS1 Syntax Engine,这是一个C库,用于处理GS1应用标识符语法扫描数据的参考实现:https://github.com/gs1/gs1-syntax-engine 查找: 要获取您感兴趣的其余数据(未直接编码在条形码中),例如商品名称和制造商详细信息,需要使用外部资源查找提取的GTIN,例如本地产品数据库或可用的公共UPC数据库API之一。 GTIN本身包含原产国(实际上它代表制造商注册的国家GS1成员组织,因此不完全是原产国),制造商标识符-合称为GS1前缀,长度可变且由GS1分配,并且剩余数字表示由制造商自由分配的产品代码。 给定GTIN,一些UPC数据库只提供与GS1前缀相关的详细信息,例如GS1成员组织和制造商的文本表示形式。其他人试图保持常见项目的单个GTIN分配记录,但是这些数据将始终有些不完整和过时,因为没有强制性的实时GTIN分配注册表。 本问题 的答案提供了一些免费的产品信息平台示例。
[†] 实际上,您可能会看到]C1019501234567890310000123 {GS} 17150801 ,在这种情况下,可以丢弃GS1-128的前导符号标识符]C1

1
这是一个使用Javascript编写的解决方案,已在特定客户中得到证明,通用化需要更多的工作:
//define AI's, parameter name and, optionally, transformation functions
SapApplicationIdentifiers= [
    { ai: '00', regex: /^00(\d{18})/,         parameter: 'SSCC'},
    { ai: '01', regex: /^01(\d{14})/,         parameter: 'EAN'},
    { ai: '02', regex: /^02(\d{14})/,         parameter: 'EAN'},
    { ai: '10', regex: /^10([^\u001D]{1,20})/,  parameter: 'LOTE'},
    { ai: '13', regex: /^13(\d{6})/},
    { ai: '15', regex: /^15(\d{6})/,        parameter: 'F_CONS', transform: function(match){ return '20'+match[1].substr(0,2)+'-'+match[1].substr(2,2)+'-'+match[1].substr(4,2);}},
    { ai: '17', regex: /^17(\d{6})/,        parameter: 'F_CONS', transform: function(match){ return '20'+match[1].substr(0,2)+'-'+match[1].substr(2,2)+'-'+match[1].substr(4,2);}},
    { ai: '19', regex: /^19(\d{6})/,        parameter: 'F_CONS', transform: function(match){ return '20'+match[1].substr(0,2)+'-'+match[1].substr(2,2)+'-'+match[1].substr(4,2);}},
    { ai: '21', regex: /^21([\d\w]{1,20})/},                       //numero de serie
    { ai: '30', regex: /^30(\d{1,8})/},
    { ai: '310', regex: /^310(\d)(\d{6})/, parameter: 'NTGEW', transform: function(match){ return parseInt( match[2] ) / Math.pow( 10,parseInt( match[1] ) )}},
    { ai: '320', regex: /^320(\d)(\d{6})/, parameter: 'NTGEW', transform: function(match){ return parseInt( match[2] ) / Math.pow( 10,parseInt( match[1] ) )}},
    { ai: '330', regex: /^330(\d)(\d{6})/},
    { ai: '37', regex: /^37(\d{1,8})/,        parameter: 'CANT'}
  ];

 //walks through the code, removing recognized fields
 function parseAiByAi(code, mercancia, onError ){
    var match;

    if(!code)
      return;

    SapApplicationIdentifiers.forEach(function(AI){
      if(code.indexOf(AI.ai)==0 && AI.regex.test(code)){
        match= AI.regex.exec( code );
        if(AI.parameter){
          if(angular.isFunction(AI.transform)){
            mercancia[AI.parameter] = AI.transform(match);
          }else
            mercancia[AI.parameter]= match[1];
          if(AI.parameter=="NTGEW"){
            mercancia.NTGEW_IA= AI.ai;
          }
        }

        code= code.replace(match[0],'').replace(/^[\0\u001D]/,'');
        parseAiByAi(code, mercancia, onError);
      }

    });
  }

  parseAiByAi(code, mercancia, onError);

-2
你可以尝试使用UPC数据库API。但是他们无法保证稳定性,并且每天限制1000个查询。我还找到了这个API,它收费为每1000次调用1美元。祝好运!

1
此 API 提供有关产品的信息,但不帮助解码。 - eleuteron

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接