在java, c++或c#中验证TPIN码
本文关键字:验证 TPIN java c++ | 更新日期: 2023-09-27 17:54:56
在我的大学项目中,我对TPIN验证有很小的要求,要求是,我们不应该允许用户在以下场景中设置他的TPIN。
- TPIN不应按顺序排列。(上行或下行ex: 123456, 456789, 987654或654321)
- TPIN不能从0开始(例如:0127865,098764)
- TPIN不应该是重复的数字(例如:888888,222222等)
对于第三个,我的想法是将数字除以11并检查提醒…
有什么想法吗?
public class Validate
{
public static void main(String[] args)
{
int iTpin = Integer.parseInt(args[0]); // Converted string to int
System.out.println("The entered TPIN is:"+iTpin);
boolean flag = validate(iTpin);
if (flag== true)
System.out.println("The entered TPIN is valid");
else
System.out.println("The entered TPIN is Invalid");
}
public static boolean validate(int passedTpin)
{
if (passedTpin == 0)
return false;
else if ( passedTpin%11 == 0)
return false;
else
return true;
}
}
最后为数字序列创建了代码。它可能对其他人有用
private static boolean containsRepetitiveDigits(String tpin) {
char firstChar = tpin.charAt(0);
for (int i = 1; i < tpin.length(); i++) {
char nextChar = tpin.charAt(i);
if ((Character.valueOf(nextChar)).compareTo(Character
.valueOf(firstChar)) != 0) {
return false;
}
}
System.out.println("Error:TPIN contains repetitive digits");
return true;
}
首先,使用Int32
存储数字意味着不应该超过2,147,483,647。除此之外,一旦你转换成一个数字,你将无法检查前导零,因为一旦你得到一个数字,前导零显然会消失。
这意味着您应该在验证期间将输入保持为string
。这实际上使您的工作更容易,因为您可以索引单个字符,而不需要使用算术运算。
由于您正在处理字符串,因此您还应该在执行其他操作之前检查输入字符串是否包含无效(非数字)字符:
bool ContainsInvalidCharacters(string input)
{
// check if there is a non-digit character
foreach (char c in input)
if (!char.IsDigit(c))
return true;
return false;
}
然后您可以继续添加单个规则。例如,要检查字符是否重复,您可以这样做:
bool ContainsRepetitiveDigits(string input)
{
if (input.Length == 0)
return false;
// get the first character
char firstChar = input[0];
// check if there is a different character
foreach (char c in input)
if (c != firstChar)
return false;
// if not, it means it's repetitive
return true;
}
bool StartsWithZero(string input)
{
if (input.Length == 0)
return false;
return (input[0] == '0');
}
要检测序列,最直接的方法是获取前两个字符的差值,然后检查它是否在整个字符串中发生变化:
bool IsSequence(string input)
{
// we need at least two characters
// for a sequence
if (input.Length < 2)
return false;
// get the "delta" between first two
// characters
int difference = input[1] - input[0];
// allowed differences are:
// -1: descending sequence
// 0: repetitive digits
// 1: ascending sequence
if (difference < -1 || difference > 1)
return false;
// check if all characters are equally
// distributed
for (int i = 2; i < input.Length; i++)
if (input[i] - input[i - 1] != difference)
return false;
// this is a sequence
return true;
}
一旦你定义了所有的规则,你就可以创建一个方法来逐一测试它们:
bool Validate(string input)
{
// list of all predicates to check
IEnumerable<Predicate<string>> rules = new Predicate<string>[]
{
ContainsInvalidCharacters,
ContainsRepetitiveDigits,
StartsWithZero,
IsSequence
};
// check if any rule matches
foreach (Predicate<string> check in rules)
if (check(input))
return false;
// if no match, it means input is valid
return true;
}
注意IsSequence
也检测到重复的数字模式(当字符差为零时)。如果要显式地防止这种情况,请更改检查允许的差异的条件。或者,您可以完全删除ContainsRepetitiveDigits
规则。
[编辑]
既然我看到你在使用Java而不是c#,我将试着提供一个更好的例子。
免责声明:我通常不使用Java编程,但据我所知,Java不像c#那样支持委托。因此,我将尝试提供一个Java示例(希望它能工作),它能更好地表达我的"复合验证"意图。
(后面跟着可疑的Java代码)
首先,定义一个所有验证规则都将实现的接口:
// (java code)
/**
* Defines a validation rule.
*/
public interface IValidationRule
{
/**
* Returns a description of this
* validation rule.
*/
String getDescription();
/**
* Returns true if this rule
* is matched.
*/
boolean matches(String tpin);
}
接下来,在单独的类中定义每个规则,实现getDescription
和matches
方法:
// (java code)
public class RepetitiveDigitsRule implements IValidationRule
{
public String getDescription()
{
return "TPIN contains repetitive digits";
}
public boolean matches(String tpin)
{
char firstChar = tpin.charAt(0);
for (int i = 1; i < tpin.length(); i++)
if (tpin.charAt(i) != firstChar)
return false;
return true;
}
}
public class StartsWithZeroRule implements IValidationRule
{
public String getDescription()
{
return "TPIN starts with zero";
}
public boolean matches(String tpin)
{
if (tpin.length() < 1)
return false;
return tpin.charAt(0) == '0';
}
}
您可以看到matches
方法不向控制台打印任何内容。如果规则匹配,它简单地返回true
,并留给它的调用者决定是否打印它的描述(到控制台,消息框,网页,等等)。
最后,您可以实例化所有已知的规则(IValidationRule
的实现)并逐一检查它们:
// (java code)
public class Validator
{
// instantiate all known rules
IValidationRule[] rules = new IValidationRule[] {
new RepetitiveDigitsRule(),
new StartsWithZeroRule()
};
// validate tpin using all known rules
public boolean validate(String tpin)
{
System.out.print("Validating TPIN " + tpin + "... ");
// for all known rules
for (int i = 0; i < rules.length; i++)
{
IValidationRule rule = rules[i];
// if rule is matched?
if (rule.matches(tpin))
{
// print rule description
System.out.println("Error: " + rule.getDescription());
return false;
}
}
System.out.println("Success.");
return true;
}
}
我建议尝试遵循这个模式。您将得到更容易重用和维护的代码。
可以生成顺序tpin(升序&降序),然后将其与输入的tpin进行比较。如果匹配则无效。
public static bool IsSequential(string pin, bool descending)
{
int p = Convert.ToInt32(pin.Substring(0,1));
string tpin = string.Empty;
for (int i = 0; i < 6; i++)
{
tpin += descending ? (p--).ToString() : (p++).ToString();
}
return pin.Equals(tpin);
}
对于第3项,你不能只除以11,因为有些引脚的余数是0。(即221199是一个有效的数字,但余数为0)。您可以获取第一个数字,并使用循环与其余数字进行比较。