java 如何使用包含空格的信用卡号?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/875867/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I use credit card numbers containing spaces?
提问by Tom Hawtin - tackline
Some fancy websites show an error dialog when it is detected that an untrained shopper has entered a credit/debit card number as it is printed on their card with spaces. Is it possible in some way to write a Java web app that handles these numbers with spaces as if they were correct?
当检测到未经培训的购物者输入了信用卡/借记卡号码时,一些花哨的网站会显示错误对话框,因为信用卡/借记卡号码印在他们的卡上并带有空格。是否有可能以某种方式编写一个 Java Web 应用程序来处理这些带有空格的数字,就好像它们是正确的一样?
回答by cletus
My view is that any Web app that rejects a credit card number with spaces isn't doing its job. When you receive a credit card number, it's easy enough to do:
我的观点是,任何拒绝带有空格的信用卡号的 Web 应用程序都没有发挥作用。当您收到信用卡号时,很容易做到:
String ccNumber = ccNumber.replaceAll("[\s-]+", "");
to remove spaces and dashes (some use those too). Then validate the result. You'll simply annoy your users if you force them to remove spaces you could just as easily do.
删除空格和破折号(有些也使用这些)。然后验证结果。如果您强迫他们删除您可以轻松执行的空格,您只会惹恼您的用户。
As for howto validate, well that depends on a lot of things, such as which Web framework you're using and what validation options you've chosen. Struts 1 for example might or might not use Apache Commons Validator whereas Spring MVC will (probably) use Spring validation and so on. So I can't tell you exactly how to validate but I can tell you whatto validate.
至于如何验证,这取决于很多事情,例如您使用的 Web 框架以及您选择的验证选项。例如,Struts 1 可能会或可能不会使用 Apache Commons Validator,而 Spring MVC 将(可能)使用 Spring 验证等等。所以我不能确切地告诉你如何验证,但我可以告诉你要验证什么。
The first thing is that a CC number with spaces should notbe rejected. Most people will find:
的第一件事是,随着空格的CC数应该不会被拒绝。大多数人会发现:
4123 0987 8876 2939
mucheasier to read than:
比以下内容更容易阅读:
4123098788762939
which is really important if the user misses or mistypes a digit and needs to find why his or her credit card number failed validation. The replaceAll() at the top of this post covers this situation.
如果用户遗漏或错误输入数字并且需要找出他或她的信用卡号码验证失败的原因,这非常重要。这篇文章顶部的 replaceAll() 涵盖了这种情况。
The second thing is that you display the credit card number (even when some of the digits are replaced with X for security reasons) in the correct way. I suggest you read through Anatomy of Credit Card Numbers.
第二件事是您以正确的方式显示信用卡号(即使出于安全原因将某些数字替换为 X)。我建议你通读信用卡号码剖析。
That page gives you the rules for the number of digits and the valid prefixes. A robust Web application will implement these so you can tell if a credit card number is invalid before you try and use it. It can take up to 30 seconds (or possibly more) to submit credit card details to a payment gateway so you shouldn't do it until you are sure as you can be that the payment will be accepted. To do otherwise is to provide a really bad user experience. There is every chance the user will give up if it fails 1-2 times rather than wait.
该页面为您提供了位数和有效前缀的规则。一个健壮的 Web 应用程序将实现这些,因此您可以在尝试使用之前判断信用卡号是否无效。将信用卡详细信息提交到支付网关最多可能需要 30 秒(或可能更长),因此在您确定付款将被接受之前,您不应这样做。否则会提供非常糟糕的用户体验。如果失败 1-2 次,用户很可能会放弃而不是等待。
As for displaying them, that depends on the # of digits:
至于显示它们,这取决于数字的数量:
- 16: 4 groups of 4 separated by a space;
- 15: like an American Expresscard ie 4-6-5 with a space between each group;
- 14: like a Diners Clubcard ie 4-6-4 with a space between each group;
- 13: Never seen 13 but 4-5-4 or 4-4-5 or 5-4-4 (or possibly 3-3-3-4) springs to mind.
- 16:4组4个用空格隔开;
- 15:像一张美国运通卡,即4-6-5,每组之间有一个空格;
- 14:像Diners Club卡,即 4-6-4,每组之间有一个空格;
- 13: 从未见过 13 但 4-5-4 或 4-4-5 或 5-4-4 (或可能 3-3-3-4) 浮现在脑海中。
The credit card number should be verified according to the checksum algorithm mentioned in the page before submitting for processingas part of a standard validation routine. That page has a Java implementation of that routine.
作为标准验证程序的一部分提交进行处理之前,应根据页面中提到的校验和算法验证信用卡号。该页面具有该例程的 Java 实现。
Everywebsite that accepts credit card payment should be doing all of the above as an absolute minimumor you're simply throwing away business as a percentage of your users get frustrated.
每个接受信用卡付款的网站都应该将上述所有内容作为绝对最低限度,否则您只是因为一部分用户感到沮丧而放弃业务。
So the short version is two simple rules:
所以简短的版本是两个简单的规则:
- Be as forgiving as possible with user input; and
- Do absolutely everything possible to validate credit card details prior to submission.
- 对用户输入尽可能宽容;和
- 在提交之前,尽一切可能验证信用卡详细信息。
回答by Bill the Lizard
I would go as far as stripping out all non-numeric characters then checking that the length is valid before running the user input through real validation like Luhn's algorithm.
我会尽可能去除所有非数字字符,然后在通过像Luhn 算法这样的真实验证运行用户输入之前检查长度是否有效。
String ccNumber = input.replaceAll("\D", "");
strips out all the non-digits from String input.
从 中去除所有非数字String input。
回答by kenj0418
Websites that force you to enter credit card numbers (and similar things) in a specific format - seriously annoy me.
强迫您以特定格式输入信用卡号(和类似内容)的网站 - 真让我烦恼。
Those people are inconveniencing their customers simply because they (the developers) are lazy. There is no reason not to accept things like credit card numbers, phone numbers, etc in whatever format they are provided. The only limitation is what is REQUIRED to understand how to interpret the value.
这些人只是因为他们(开发人员)懒惰而给他们的客户带来不便。没有理由不接受信用卡号、电话号码等以任何格式提供的信息。唯一的限制是需要了解如何解释值。
You shouldn't care whether I enter 5555-4444-3333-2222 or 5555444433332222, just strip the dashes out if you don't like them - same with spaces. And with phone numbers, unless you are going to be auto-dialing the number, you probably don't even care what format its in so don't annoy your users unless you have to.
你不应该关心我是输入 5555-4444-3333-2222 还是 5555444433332222,如果你不喜欢它们,就去掉破折号——空格也是一样。对于电话号码,除非您要自动拨打该号码,否则您可能甚至不在乎它的格式,因此除非必须,否则不要惹恼您的用户。
回答by skiphoppy
Unfortunately, no. Java just cannot handle these requirements, since there is so much overhead involved in emulating the Java Virtual Machine on x86 chips, leaving no room for useful constructs like Perl's regular expressions, which can do it thusly:
抱歉不行。Java 无法处理这些需求,因为在 x86 芯片上模拟 Java 虚拟机涉及太多开销,没有为像 Perl 的正则表达式这样的有用构造留出空间,它可以这样做:
$input =~ s/\D//g;
Java made an attempt at adding regular expressions a few years back, but they only ran on PowerPC chips, which are no longer used. The problem was that all regular expressions had to be contained as Strings instead of being a first class language construct, and thus doubling backslashes was required, but as everyone knows backslashes mean something different on the primary operating system for the x86 architecture.
几年前,Java 曾尝试添加正则表达式,但它们只能在不再使用的 PowerPC 芯片上运行。问题是所有正则表达式都必须包含为字符串而不是一流的语言结构,因此需要加倍反斜杠,但众所周知,反斜杠在 x86 架构的主要操作系统上的含义有所不同。
My advice is to upgrade to Perl. Scheme is also known to be able to handle this situation as well as give a tremendous advantage over your competition, but Scheme runs only on LISP machines.
我的建议是升级到 Perl。众所周知,Scheme 能够处理这种情况并在您的竞争对手中提供巨大的优势,但 Scheme 只能在 LISP 机器上运行。
回答by ChrisW
Unfortunately not, which why instead those fancy web sites need to show an error dialog to the untrained shopper: to force the shopperto re-enter their number, in the format that the machine prefers.
不幸的是,这不是为什么那些花哨的网站需要向未经培训的购物者显示一个错误对话框:强制购物者以机器喜欢的格式重新输入他们的号码。
Why, if only a machinecould do "data processing", so that the machine itself could change the data format! Or, if only if there were no such thing as an "untrained" shopper! Alas!
为什么,如果只有一台机器可以进行“数据处理”,让机器本身可以改变数据格式!或者,如果没有“未经训练的”购物者这样的东西就好了!唉!
回答by Pyrolistical
Easy.
简单。
- Your input space is a list of characters from some character set containing all characters.
- Your output space is a list of characters from some character set containing only numbers.
- 您的输入空间是包含所有字符的某个字符集中的字符列表。
- 您的输出空间是来自某些仅包含数字的字符集的字符列表。
To solve this problem, we create an intermediate space containing only the numbers 0 to 9. We can create a new enum for this finite set. We'll call this our finger space, since it oddly contains the same number of members as we do fingers.
为了解决这个问题,我们创建了一个只包含数字 0 到 9 的中间空间。我们可以为这个有限集创建一个新的枚举。我们将其称为我们的手指空间,因为奇怪的是,它包含的成员数量与我们的手指空间相同。
We then write two functions.
然后我们写两个函数。
- Convert input space to finger space
- Convert finger space to output space
- 将输入空间转换为手指空间
- 将手指空间转换为输出空间
As we reduce the input space to the finger space, we just drop any character not found in the finger space. Converting from finger space to output space is even easier. We just find the same number in the output space.
当我们将输入空间减少到手指空间时,我们只是删除手指空间中找不到的任何字符。从手指空间转换到输出空间更容易。我们只是在输出空间中找到相同的数字。
The trick is for this to work with all character sets. I haven't figured out how to determine if a certain character matches a member in my finger set. Maybe I should post it as a question.
诀窍是它适用于所有字符集。我还没有弄清楚如何确定某个字符是否与我的手指组中的某个成员匹配。也许我应该把它作为一个问题发布。
回答by user67143
Your question seems strange but I would think that it should be as easy as running the credit card numbers entered by users through a validation function which would first of all remove all white spaces.
您的问题似乎很奇怪,但我认为它应该像通过验证功能运行用户输入的信用卡号一样简单,该功能首先会删除所有空格。
This is rather trivial in any modern language with or without using regex.
无论是否使用正则表达式,这在任何现代语言中都是相当微不足道的。
回答by Robert Greiner
Tom,
汤姆,
The problem is solved technically, let's talk about it theoretically.
技术上解决了问题,我们从理论上说一下。
There are two schools of thought here. I do not think it is an acceptable answer to say "if the user can't figure it out it's their problem."
这里有两种思想流派。我认为说“如果用户无法弄清楚这是他们的问题”是不可接受的答案。
- Be firm about your user input and only accept credit card numbers that are well-formed. This requires keeping the user on the page until they get everything right.
- Be more lenient by assuming their intentions and adjusting their input for them (just be sure to give them a confirmation screen to verify the new input).
- 对您的用户输入保持坚定,只接受格式正确的信用卡号。这需要将用户留在页面上,直到他们做对了一切。
- 通过假设他们的意图并调整他们的输入来更宽容(一定要给他们一个确认屏幕来验证新输入)。
In my opinion, #2 is the way to go, you can use regular expressions (as stated above) to pull all spaces, special characters, etc. out of the cc# field and keep the user from having to enter their information again.
在我看来,#2 是可行的方法,您可以使用正则表达式(如上所述)将所有空格、特殊字符等从 cc# 字段中提取出来,并使用户不必再次输入他们的信息。
Either way you should inform the user of the proper input form (i.e. xxxx-xx-xxxx)
无论哪种方式,您都应该通知用户正确的输入形式(即 xxxx-xx-xxxx)
as a rule of thumb, I tend to appreciate sites that are more elegant about the way they handle user input.
根据经验,我倾向于欣赏处理用户输入方式更优雅的网站。
For more tips on regular expressions check out regular-expressions . info
有关正则表达式的更多提示,请查看正则表达式。信息
Good luck,
祝你好运,
-Robert
-罗伯特
回答by Orclev
I'm going to assume this is a real question even though it looks like some sort of troll or joke.
我会假设这是一个真正的问题,即使它看起来像某种巨魔或笑话。
You should model your interface so that the user instinctively performs the input in a controlled manner. Simply put, ask them for the kind of card first, and then on the input form format the input to match the card. For example, assuming a 16 digit card like Visa or Mastercard, display 4 input boxes separated by spaces or dashes that limit input to 4 characters each and automatically move to the next box in the series after the user types the fourth digit.
您应该为您的界面建模,以便用户以受控方式本能地执行输入。简单地说,先问他们要哪种卡片,然后在输入表单上格式化输入以匹配卡片。例如,假设有一张 16 位卡,如 Visa 或 Mastercard,显示 4 个输入框,由空格或破折号分隔,每个输入框限制输入 4 个字符,并在用户键入第四个数字后自动移动到系列中的下一个框。
It should look something like the following on the page:
它应该类似于页面上的以下内容:
Card Number:
[1234] - [1234] - [1234] - [1234]
卡号:
[1234] - [1234] - [1234] - [1234]
or
或者
Card Number:
[1234] - [123456] - [12345]
卡号:
[1234] - [123456] - [12345]
回答by AAA
There are a number of options, but the most logical seems to be to just do a simple string replace to replace all the spaces with a closed character i.e. ''. This will reduce the credit card string to just one long string of numbers..then just process away
有多种选择,但最合乎逻辑的似乎是只进行简单的字符串替换,用封闭字符(即 '')替换所有空格。这会将信用卡字符串减少为一长串数字..然后就可以处理了

