信用卡跟踪数据的正则表达式

时间:2022-01-19 17:47:07

Are there any known regular expressions out there to validate credit card track 1 and track 2 data?

是否有已知的正则表达式来验证信用卡跟踪1和跟踪2数据?

EDIT:

编辑:

From Wikipedia:

从*:

The information on track 1 on financial cards is contained in several formats: A, which is reserved for proprietary use of the card issuer, B, which is described below, C-M, which are reserved for use by ANSI Subcommittee X3B10 and N-Z, which are available for use by individual card issuers:

关于第1条关于金融卡的信息包含了几种格式:A是专为发卡人使用的,B是下文所述的,C-M是为ANSI小组委员会X3B10和N-Z使用的,供个别发卡人使用:

Track 1, Format B:

轨道1,B格式:

  • Start sentinel — one character (generally '%')
  • 启动前哨-一个字符(一般为'%')
  • Format code="B" — one character (alpha only)
  • 格式码="B" -一个字符(只适用于字母)
  • Primary account number (PAN) — up to 19 characters. Usually, but not always, matches the credit card number printed on the front of the card.
  • 主要帐号(PAN) -最多19个字符。通常情况下,但并不总是与信用卡正面的信用卡号码相匹配。
  • Field Separator — one character (generally '^')
  • 字段分隔符——一个字符(通常“^”)
  • Name — two to 26 characters
  • 名字- 2到26个字符
  • Field Separator — one character (generally '^')
  • 字段分隔符——一个字符(通常“^”)
  • Expiration date — four characters in the form YYMM.
  • 有效期- YYMM格式中的四个字符。
  • Service code — three characters
  • 服务代码-三个字符
  • Discretionary data — may include Pin Verification Key Indicator (PVKI, 1 character), PIN Verification Value (PVV, 4 characters), Card Verification Value or Card Verification Code (CVV or CVK, 3 characters)
  • 可*支配的数据——可包括Pin验证密钥指示器(PVKI, 1个字符)、Pin验证值(PVV, 4个字符)、Card验证值或Card验证码(CVV或CVK, 3个字符)
  • End sentinel — one character (generally '?')
  • End sentinel -一个字符(通常是“?”)
  • Longitudinal redundancy check (LRC) — it is one character and a validity character calculated from other data on the track. It should be noted that most reader devices do not return this value when the card is swiped to the presentation layer, and use it only to verify the input internally to the reader.
  • 纵向冗余校验(LRC) -它是一个字符和一个有效字符计算从其他数据在轨道上。需要注意的是,当刷卡到表示层时,大多数阅读器设备都不会返回这个值,并且只在内部验证输入给阅读器。

Track 2: This format was developed by the banking industry (ABA). This track is written with a 5-bit scheme (4 data bits + 1 parity), which allows for sixteen possible characters, which are the numbers 0-9, plus the six characters : ; < = > ? . The selection of six punctuation symbols may seem odd, but in fact the sixteen codes simply map to the ASCII range 0x30 through 0x3f, which defines ten digit characters plus those six symbols. The data format is as follows:

跟踪2:这种格式是由银行业(ABA)开发的。这首歌采用了5位格式(4位数据+ 1位奇偶校验),允许输入16个可能的字符,这些字符是数字0-9,加上6个字符:< = > ?。选择6个标点符号似乎有些奇怪,但实际上这16个代码只是映射到ASCII范围0x30到0x3f,它定义了10个数字字符加上这6个符号。数据格式如下:

  • Start sentinel — one character (generally ';')
  • 启动前哨-一个字符(一般是';')
  • Primary account number (PAN) — up to 19 characters. Usually, but not always, matches the credit card number printed on the front of the card.
  • 主要帐号(PAN) -最多19个字符。通常情况下,但并不总是与信用卡正面的信用卡号码相匹配。
  • Separator — one char (generally '=')
  • 分隔符—一个字符(一般是'=')
  • Expiration date — four characters in the form YYMM.
  • 有效期- YYMM格式中的四个字符。
  • Service code — three characters
  • 服务代码-三个字符
  • Discretionary data — as in track one
  • 可*支配的数据——如跟踪一
  • End sentinel — one character (generally '?')
  • End sentinel -一个字符(通常是“?”)
  • Longitudinal redundancy check (LRC) — it is one character and a validity character calculated from other data on the track. It should be noted that most reader devices do not return this value when the card is swiped to the presentation layer, and use it only to verify the input internally to the reader.
  • 纵向冗余校验(LRC) -它是一个字符和一个有效字符计算从其他数据在轨道上。需要注意的是,当刷卡到表示层时,大多数阅读器设备都不会返回这个值,并且只在内部验证输入给阅读器。

5 个解决方案

#1


2  

I was about to post the same link on regular-expressions.info, for verifying the cc number part of the track.

我正要在常规的表达式。info上发布同样的链接,用于验证曲目的cc号部分。

Now, comes the tricky part. Track data varies in format between card issuers and even card readers. For example the 'separator' characters aren't always the same. Same applies to the end 'sentinels'.

现在,棘手的部分来了。跟踪数据在发卡机构和甚至读卡器之间的格式不同。例如,“分隔符”字符并不总是相同的。最后的“哨兵”也一样。

Wikipedia gives a good overview: http://en.wikipedia.org/wiki/Magnetic_stripe_card

Wikipedia提供了一个很好的概述:http://en.wikipedia.org/wiki/Magnetic_stripe_card

With track2, the card number is followed by an '=' (or occasionally a 'D'). Then you have expiry date as MMDD. After that, Track2 has 'discretionary data', which could be anything.

使用track2,卡号后面跟着一个'='(或者偶尔一个'D')。然后有MMDD的有效期。之后,Track2就有“可*支配的数据”,可以是任何东西。

I wouldn't worry too much after this point. If it's track data, you'll be pretty sure by now. I guess it depends on what you are aiming to do with the data.

在这之后我不会太担心。如果是跟踪数据,你现在就能很确定了。我想这取决于你打算如何处理这些数据。

Anyway, for Track2 you could do a lot worse than adding [=D][0-9]{4} instead of the $ at the end of the cc regex:

不管怎样,对于Track2,你可以做得比添加[=D][0-9]{4}要糟糕得多,而不是在cc regex末尾的$:

^(?: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}

For track1, you could do something similar ... Track1 contains more variable data, so can be a touch more complicated.

对于track1,你可以做一些类似的事情……Track1包含了更多的可变数据,因此可以更复杂一些。

Good luck!

好运!

#2


8  

Here is a REGEX that works for me to pick both Track 1 and Track 2. Use this with the regex option "Dot does NOT match newline".

这里有一个REGEX,可以让我同时选择轨道1和轨道2。使用这个与regex选项“Dot不匹配换行”一起使用。

^%(?<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

I tested with this data (my reader is reading both a Track 1 and Track 2 record, in this order, for the same card I tested with - numbers and name changed below.)

我用这些数据进行了测试(我的读者正在读取记录1和记录2,按照这个顺序,读取我测试过的同一张卡片——下面更改了数字和名称)。

%B5581123456781323^SMITH/JOHN^16071021473810559010203?
;5581123456781323=160710212423468?

The above REGEX uses NAMED CAPTURE GROUPS (the "?" that starts out each (group)) and I see the result (with RegexBuddy) as:

上面的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

Note the second match does NOT identify FC (format code) and NM (name) in the Track 2 (match 2) since they are not used in track 2.

注意,第二个匹配在第2条(第2条)中没有标识FC(格式代码)和NM(名称),因为它们在第2条中没有使用。

If your regex engine does not support NAMED GROUPS, just kill the "?" part of each of the capturing groups. Then, use position to determine each group.

如果您的regex引擎不支持命名组,那么只需杀死每个捕获组的“?”部分。然后,使用位置来确定每个组。

Also, my single SWIPE contains BOTH track 1 and track 2 (in that order, track 1, a crlf and then track 2). According to the Wikipedia link in the original question, cards can have up to 3 tracks and readers might read tracks 1 and 2 both (or one or the other) and rarely track 3.

同时,我单刷既包含跟踪1和跟踪2(轨道1,依次crlf然后跟踪2)。据*链接在最初的问题,卡可以有3跟踪和读者可能读取跟踪1和2(或其中之一)和很少追踪3。

For this reason, I think it's a safe bet to use a REGEX that looks for both track 1 and track 2 and if you get both, you can ignore track 2 (since track 1 has more data) or whatever you wish.

出于这个原因,我认为使用一个同时查找第1和第2条的REGEX是一个安全的选择,如果您同时获得了第2条,那么您可以忽略第2条(因为第1条有更多的数据)或任何您想要的东西。

Because both tracks are present in my swipes, the REGEX engine will return 2 matches with my REGEX above (assuming no read error from the reader and a reader that supports both tracks). In my case, this does not bother me and I'll simply plan to use the "first match" and ignore the second.

因为这两个轨道都在我的刷新中,所以REGEX引擎将返回与上面的REGEX匹配的两个匹配(假设读取器和支持这两个轨道的读取器没有读取错误)。在我的例子中,这并不困扰我,我只打算使用“第一场比赛”而忽略第二场比赛。

If you're interested only in track 1, use this regex:

如果您只对第1条感兴趣,请使用此regex:

^%(?<FC>.)(?<PAN>[\d]{1,19}+)\^(?<NM>.{2,26})\^(?<ED>[\d]{0,4}|\^)(?<SC>[\d]{0,3}|\^)(?<DD>.*)\?\Z

If you're interested only in track 2, use the regex:

如果你只对轨道2感兴趣,可以使用regex:

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

But I see no harm in checking for both and then using the first one you get, or perhaps comparing track 1 to track 2 as an additional error checking step perhaps.

但是我认为检查这两种方法都没有什么害处,然后使用您得到的第一个方法,或者可能将跟踪1与跟踪2进行比较,作为额外的错误检查步骤。

Sorry to answer what seems to be answered!

不好意思回答你的问题!

#3


2  

The following two regular expressions seem to validate the track 1 and track 2 data. Note that these regular expressions make assumptions that the characters used are the ones that are "generally" used in the Wikipedia information above.

以下两个正则表达式似乎验证了跟踪1和跟踪2的数据。注意,这些正则表达式假设所使用的字符是上面Wikipedia信息中“一般”使用的字符。

Track 1:  ^%B\d{0,19}\^[\w\s\/]{2,26}\^\d{7}\w*\?$

Assumes that % and ? are the sentinel characters and that ^ is used as the field separator character. Also assumes that the account number, date, and service code are digits.

假设%和?哨兵字符^是作为字段分隔符字符。还假设帐户号、日期和服务代码是数字。

Track 2:  ;\d{0,19}=\d{7}\w*\?

Assumes that ; and ? are the sentinel characters and that = is the field separator character. Also assumes that the account number, date, and service code are digits.

假设;然后呢?为sentinel字符,=字段分隔符。还假设帐户号、日期和服务代码是数字。

I tested these expressions using track data read from a MagTek card reader. The following two sets of track data match what was read from the reader and validate against the two regular expressions above (the numbers have obviously been changed):

我使用MagTek读卡器读取的跟踪数据测试了这些表达式。以下两组跟踪数据与读取器读取的内容相匹配,并与上面的两个正则表达式进行验证(数字明显发生了变化):

%B1234567891234567^SMITH/JOHN                ^15024041234567891234?
;1234567891234567=152024041234567891234?

#4


1  

Track 1, Format B translates to

轨道1,格式B转换为。

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

with some assumptions as to what constitutes a valid character.

有一些关于什么构成一个有效字符的假设。

Of course there are no checks whether the data is actually meaningful, and the LRC (if present) also can't be validated.

当然,没有检查数据是否具有实际意义,而LRC(如果存在)也不能被验证。

Can you check this against some real data and see if it works?

你能不能核对一下真实的数据,看看是否有效?

Track 2 translates to

跟踪2翻译

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

#5


0  

Note: Account number in track1 can contain spaces for American Express cards. So :

注意:track1中的帐号可以包含美国运通卡的空格。所以:

^%(?.)(?[\d\s]{1,19}+)\^(?.{2,26})\^(?[\d]{0,4}|\^)(?[\d]{0,3}|\^)(?.*)\?|;(?[\d]{1,19}+)=(?[\d]{0,4}|=)(?[\d]{0,3}|=)(?.*)\?\Z

#1


2  

I was about to post the same link on regular-expressions.info, for verifying the cc number part of the track.

我正要在常规的表达式。info上发布同样的链接,用于验证曲目的cc号部分。

Now, comes the tricky part. Track data varies in format between card issuers and even card readers. For example the 'separator' characters aren't always the same. Same applies to the end 'sentinels'.

现在,棘手的部分来了。跟踪数据在发卡机构和甚至读卡器之间的格式不同。例如,“分隔符”字符并不总是相同的。最后的“哨兵”也一样。

Wikipedia gives a good overview: http://en.wikipedia.org/wiki/Magnetic_stripe_card

Wikipedia提供了一个很好的概述:http://en.wikipedia.org/wiki/Magnetic_stripe_card

With track2, the card number is followed by an '=' (or occasionally a 'D'). Then you have expiry date as MMDD. After that, Track2 has 'discretionary data', which could be anything.

使用track2,卡号后面跟着一个'='(或者偶尔一个'D')。然后有MMDD的有效期。之后,Track2就有“可*支配的数据”,可以是任何东西。

I wouldn't worry too much after this point. If it's track data, you'll be pretty sure by now. I guess it depends on what you are aiming to do with the data.

在这之后我不会太担心。如果是跟踪数据,你现在就能很确定了。我想这取决于你打算如何处理这些数据。

Anyway, for Track2 you could do a lot worse than adding [=D][0-9]{4} instead of the $ at the end of the cc regex:

不管怎样,对于Track2,你可以做得比添加[=D][0-9]{4}要糟糕得多,而不是在cc regex末尾的$:

^(?: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}

For track1, you could do something similar ... Track1 contains more variable data, so can be a touch more complicated.

对于track1,你可以做一些类似的事情……Track1包含了更多的可变数据,因此可以更复杂一些。

Good luck!

好运!

#2


8  

Here is a REGEX that works for me to pick both Track 1 and Track 2. Use this with the regex option "Dot does NOT match newline".

这里有一个REGEX,可以让我同时选择轨道1和轨道2。使用这个与regex选项“Dot不匹配换行”一起使用。

^%(?<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

I tested with this data (my reader is reading both a Track 1 and Track 2 record, in this order, for the same card I tested with - numbers and name changed below.)

我用这些数据进行了测试(我的读者正在读取记录1和记录2,按照这个顺序,读取我测试过的同一张卡片——下面更改了数字和名称)。

%B5581123456781323^SMITH/JOHN^16071021473810559010203?
;5581123456781323=160710212423468?

The above REGEX uses NAMED CAPTURE GROUPS (the "?" that starts out each (group)) and I see the result (with RegexBuddy) as:

上面的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

Note the second match does NOT identify FC (format code) and NM (name) in the Track 2 (match 2) since they are not used in track 2.

注意,第二个匹配在第2条(第2条)中没有标识FC(格式代码)和NM(名称),因为它们在第2条中没有使用。

If your regex engine does not support NAMED GROUPS, just kill the "?" part of each of the capturing groups. Then, use position to determine each group.

如果您的regex引擎不支持命名组,那么只需杀死每个捕获组的“?”部分。然后,使用位置来确定每个组。

Also, my single SWIPE contains BOTH track 1 and track 2 (in that order, track 1, a crlf and then track 2). According to the Wikipedia link in the original question, cards can have up to 3 tracks and readers might read tracks 1 and 2 both (or one or the other) and rarely track 3.

同时,我单刷既包含跟踪1和跟踪2(轨道1,依次crlf然后跟踪2)。据*链接在最初的问题,卡可以有3跟踪和读者可能读取跟踪1和2(或其中之一)和很少追踪3。

For this reason, I think it's a safe bet to use a REGEX that looks for both track 1 and track 2 and if you get both, you can ignore track 2 (since track 1 has more data) or whatever you wish.

出于这个原因,我认为使用一个同时查找第1和第2条的REGEX是一个安全的选择,如果您同时获得了第2条,那么您可以忽略第2条(因为第1条有更多的数据)或任何您想要的东西。

Because both tracks are present in my swipes, the REGEX engine will return 2 matches with my REGEX above (assuming no read error from the reader and a reader that supports both tracks). In my case, this does not bother me and I'll simply plan to use the "first match" and ignore the second.

因为这两个轨道都在我的刷新中,所以REGEX引擎将返回与上面的REGEX匹配的两个匹配(假设读取器和支持这两个轨道的读取器没有读取错误)。在我的例子中,这并不困扰我,我只打算使用“第一场比赛”而忽略第二场比赛。

If you're interested only in track 1, use this regex:

如果您只对第1条感兴趣,请使用此regex:

^%(?<FC>.)(?<PAN>[\d]{1,19}+)\^(?<NM>.{2,26})\^(?<ED>[\d]{0,4}|\^)(?<SC>[\d]{0,3}|\^)(?<DD>.*)\?\Z

If you're interested only in track 2, use the regex:

如果你只对轨道2感兴趣,可以使用regex:

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

But I see no harm in checking for both and then using the first one you get, or perhaps comparing track 1 to track 2 as an additional error checking step perhaps.

但是我认为检查这两种方法都没有什么害处,然后使用您得到的第一个方法,或者可能将跟踪1与跟踪2进行比较,作为额外的错误检查步骤。

Sorry to answer what seems to be answered!

不好意思回答你的问题!

#3


2  

The following two regular expressions seem to validate the track 1 and track 2 data. Note that these regular expressions make assumptions that the characters used are the ones that are "generally" used in the Wikipedia information above.

以下两个正则表达式似乎验证了跟踪1和跟踪2的数据。注意,这些正则表达式假设所使用的字符是上面Wikipedia信息中“一般”使用的字符。

Track 1:  ^%B\d{0,19}\^[\w\s\/]{2,26}\^\d{7}\w*\?$

Assumes that % and ? are the sentinel characters and that ^ is used as the field separator character. Also assumes that the account number, date, and service code are digits.

假设%和?哨兵字符^是作为字段分隔符字符。还假设帐户号、日期和服务代码是数字。

Track 2:  ;\d{0,19}=\d{7}\w*\?

Assumes that ; and ? are the sentinel characters and that = is the field separator character. Also assumes that the account number, date, and service code are digits.

假设;然后呢?为sentinel字符,=字段分隔符。还假设帐户号、日期和服务代码是数字。

I tested these expressions using track data read from a MagTek card reader. The following two sets of track data match what was read from the reader and validate against the two regular expressions above (the numbers have obviously been changed):

我使用MagTek读卡器读取的跟踪数据测试了这些表达式。以下两组跟踪数据与读取器读取的内容相匹配,并与上面的两个正则表达式进行验证(数字明显发生了变化):

%B1234567891234567^SMITH/JOHN                ^15024041234567891234?
;1234567891234567=152024041234567891234?

#4


1  

Track 1, Format B translates to

轨道1,格式B转换为。

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

with some assumptions as to what constitutes a valid character.

有一些关于什么构成一个有效字符的假设。

Of course there are no checks whether the data is actually meaningful, and the LRC (if present) also can't be validated.

当然,没有检查数据是否具有实际意义,而LRC(如果存在)也不能被验证。

Can you check this against some real data and see if it works?

你能不能核对一下真实的数据,看看是否有效?

Track 2 translates to

跟踪2翻译

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

#5


0  

Note: Account number in track1 can contain spaces for American Express cards. So :

注意:track1中的帐号可以包含美国运通卡的空格。所以:

^%(?.)(?[\d\s]{1,19}+)\^(?.{2,26})\^(?[\d]{0,4}|\^)(?[\d]{0,3}|\^)(?.*)\?|;(?[\d]{1,19}+)=(?[\d]{0,4}|=)(?[\d]{0,3}|=)(?.*)\?\Z