信用卡磁道数据的正则表达式

13

是否有已知的正则表达式用于验证信用卡磁道1和磁道2数据?

编辑:

来自维基百科

金融卡磁道1上的信息包含多种格式:A是保留给发卡方专有使用的,B如下所述,C-M保留给ANSI子委员会X3B10使用,N-Z可供各个发卡方使用:

磁道1,格式B:

  • 起始标志 - 一个字符(通常为'%')
  • 格式代码="B" - 一个字符(仅限字母)
  • 主帐号 - 最多19个字符。通常情况下是与卡片正面印刷的信用卡号匹配的。
  • 字段分隔符 - 一个字符(通常为'^')
  • 姓名 - 两到26个字符
  • 字段分隔符 - 一个字符(通常为'^')
  • 过期日期 - 四个字符,格式为YYMM。
  • 服务代码 - 三个字符
  • 自选数据 - 可包括PIN验证密钥指示器(PVKI, 1个字符),PIN验证值(PVV, 4个字符),卡验证值或卡验证码(CVV或CVK, 3个字符)
  • 结束标志 - 一个字符(通常为'?')
  • 纵向冗余校验(LRC) - 它是一个字符和一个从磁道上其他数据计算出的有效性字符。应该注意到,当刷卡器将卡片刷到表示层时,大多数读卡设备不会返回此值,并且仅在内部验证输入时才使用它。

轨道2: 这种格式是由银行业(ABA)开发的。该轨道采用了5位方案(4个数据位+1个校验位),可以表示16个可能的字符,包括数字0-9和六个字符 : ; < = > ?。选择这六个标点符号可能看起来很奇怪,但实际上这十六个代码只是映射到ASCII范围0x30到0x3f,定义了十个数字字符加上这六个符号。其数据格式如下:

  • 起始标识符——一个字符(通常为“;”)
  • 主账户号码(PAN)——最多19个字符。通常与印在卡片正面的信用卡号匹配,但并不总是匹配。
  • 分隔符——一个字符(通常为“=”)
  • 过期日期——形式为YYMM的四个字符。
  • 服务代码——三个字符
  • 自选数据——与轨道1中的类似
  • 结束标识符——一个字符(通常为“?”)
  • 纵向冗余校验(LRC)——它是一个字符和一个从轨道上其他数据计算出的有效性字符。需要注意的是,大多数读卡器设备在刷卡时不会返回此值到表示层,只在读卡器内部验证输入。

你能提供一些所述数据的例子吗? - Bryan Denny
我已经在信用卡业务中工作了一段时间,很难想象为什么你需要这个。通常,由于1、2、3轨道在发行者的领域内,你往往很难找到除了PAN、过期日期和服务代码之外的数据,而姓名数据可能也是垃圾数据,我甚至遇到过不通过Luhn检查的PAN。这就是为什么我觉得你将有相当多的生产特例来微调正则表达式,使其足够敏感,以不丢弃与ISO规范冲突的可行生产数据。 - bbozo
5个回答

11

这是我用来选择Track 1和Track 2的正则表达式。请使用“点不匹配换行符”选项的正则表达式。

^%(?<FC>.)(?<PAN>[\d]{1,19}+)\^(?<NM>.{2,26})\^(?<ED>[\d]{0,4}|\^)(?<SC>[\d]{0,3}|\^)(?<DD>.*)\?|;(?<PAN>[\d]{1,19}+)=(?<ED>[\d]{0,4}|=)(?<SC>[\d]{0,3}|=)(?<DD>.*)\?\Z
我用以下数据进行测试(我的读卡器按此顺序读取同一张卡的Track 1和Track 2记录——下面的数字和姓名已更改)。
%B5581123456781323^SMITH/JOHN^16071021473810559010203?
;5581123456781323=160710212423468?
上述 REGEX 使用了命名捕获组(每个组开头的“?”),我用 RegexBuddy 查看结果如下:
Match 1:    %B5581123456781323^SMITH/JOHN^16071021473810559010203?       0      54
Group "FC": B        1       1
Group "PAN":    5581123456781323         2      16
Group "NM": SMITH/JOHN      19      10
Group "ED": 1607        30       4
Group "SC": 102     34       3
Group "DD": 1473810559010203        37      16

Match 2:    ;5581123456781323=160710212423468?      56      34
Group "FC" did not participate in the match
Group "PAN":    5581123456781323        57      16
Group "NM" did not participate in the match
Group "ED": 1607        74       4
Group "SC": 102     78       3
Group "DD": 12423468        81       8

请注意,第二个匹配(match 2)不会识别磁道 2 中的 FC(格式代码)和 NM(名称),因为它们在磁道 2 中没有使用。

如果您的正则表达式引擎不支持命名组,请删除每个捕获组中的“?”部分。然后使用位置来确定每个组。

此外,我的单次刷卡包含磁道 1 和磁道 2(顺序为磁道 1,crlf,然后是磁道 2)。根据原始问题中的维基百科链接,卡片最多可以有三个轨道,读卡器可能同时读取轨道 1 和轨道 2(或其中之一),很少读取轨道 3。

因此,我认为使用同时查找磁道 1 和磁道 2 的正则表达式是一个安全的选择,如果您获得了两者,可以忽略磁道 2(因为磁道 1 具有更多数据)或任何您希望忽略的内容。

由于我的刷卡记录中同时出现了两个轨道,因此正则表达式引擎将使用上面的正则表达式返回 2 个匹配项(假设读卡器没有读取错误并且支持两个轨道)。在我的情况下,这并不影响我,我将简单地计划使用“第一个匹配项”并忽略第二个。

如果您只对磁道 1 感兴趣,请使用此正则表达式:

^%(?<FC>.)(?<PAN>[\d]{1,19}+)\^(?<NM>.{2,26})\^(?<ED>[\d]{0,4}|\^)(?<SC>[\d]{0,3}|\^)(?<DD>.*)\?\Z
如果您只对第二个轨道感兴趣,请使用正则表达式:

如果您只对第二个轨道感兴趣,请使用正则表达式:

^;(?<PAN>[\d]{1,19}+)=(?<ED>[\d]{0,4}|=)(?<SC>[\d]{0,3}|=)(?<DD>.*)\?\Z

但我认为检查两者并使用第一个你得到的结果没有伤害,或者将轨道1与轨道2进行比较作为额外的错误检查步骤。

抱歉回答似乎已被解决的问题!


进一步研究该问题后,发现有些礼品卡的名称为0个字符,尽管维基百科上说是2到26个字符。 - Dustin

2

我正要在regular-expressions.info上发布同样的链接,用于验证磁道中信用卡号部分。

现在,来到了棘手的部分。不同的发卡机构和读卡器之间,磁道数据的格式各不相同。例如,“分隔符”字符并不总是相同的。同样适用于结束的“哨兵”。

维基百科提供了一个很好的概述:http://en.wikipedia.org/wiki/Magnetic_stripe_card

对于track2,卡号后跟着一个“=”(或偶尔是“D”)。然后您有过期日期作为MMDD。之后,Track2有“自由数据”,可以是任何内容。

在此之后,我不会太担心。如果这是磁道数据,您现在应该非常确定了。我想这取决于您打算如何使用这些数据。

无论如何,对于Track2,您可以比将$添加到cc regex的末尾更糟糕地添加[=D][0-9]{4}:

^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})[=D][0-9]{4}

对于track1,您可以做类似的事情... Track1包含更多的可变数据,因此可能会更加复杂。

祝你好运!


2
以下两个正则表达式似乎可以验证轨道1和轨道2的数据。请注意,这些正则表达式假设所使用的字符是上面维基百科信息中“通常”使用的字符。
Track 1:  ^%B\d{0,19}\^[\w\s\/]{2,26}\^\d{7}\w*\?$

假设 % 和 ? 是哨兵字符,并且 ^ 用作字段分隔符。同时假设账号、日期和服务代码都是数字。
Track 2:  ;\d{0,19}=\d{7}\w*\?

假设分号和问号是哨兵字符,等号是字段分隔符。还假设账户号码、日期和服务代码都是数字。我使用从MagTek读卡器读取的轨道数据测试了这些表达式。以下两个轨道数据集与从读卡器读取的数据匹配,并根据上述两个正则表达式进行验证(数字显然已更改):
%B1234567891234567^SMITH/JOHN                ^15024041234567891234?
;1234567891234567=152024041234567891234?

1

轨道1,格式B翻译为

^%B[^\^\W]{0,19}\^[^\^]{2,26}\^\d{4}\w{3}[^?]+\?\w?$

在假设某些字符是有效的情况下。

当然,没有检查数据是否实际有意义,而且无法验证LRC(如果存在)。

您能否根据一些真实数据检查它是否有效?

第二轨道翻译为

;[^=]{0,19}=\d{4}\w{3}[^?]+\?\w?

我已经对这些进行了测试,但是它们与我们的读卡器数据不兼容。 - DCNYAM
看起来,“自由数据”字段允许所有的选择,而不仅仅是其中一个。我已经更改了正则表达式。现在它们应该可以工作了。 - Tim Pietzcker

0
注意:在 Track1 中的账号号码可能包含空格,适用于美国运通卡。
^%(?.)(?[\d\s]{1,19}+)\^(?.{2,26})\^(?[\d]{0,4}|\^)(?[\d]{0,3}|\^)(?.*)\?|;(?[\d]{1,19}+)=(?[\d]{0,4}|=)(?[\d]{0,3}|=)(?.*)\?\Z

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