c# - Java、C++ 或 C# 中的 TPIN 号码验证

标签 c# java c++ validation

我在大学项目中对 TPIN 验证的要求很小,要求是我们不应该允许用户在以下场景中设置他的 TPIN。

  1. TPIN 不应按顺序排列。 (升序或降序,例如:123456、456789、987654 或 654321)
  2. TPIN 不应从零开始(例如:0127865、098764)
  3. 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# 那样支持委托(delegate)。所以我会尝试提供一个Java示例(希望它能工作),它更好地表达了我的“复合验证”意图。

(后面是可疑的 Java 代码)

首先,定义一个所有验证规则都将实现的接口(interface):

// (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);
}

接下来,在单独的类中定义每个规则,实现 getDescriptionmatches 方法:

// (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,并留给它的 caller 来决定是否打印它的描述(到控制台、消息框、网页,等等)。

最后,您可以实例化所有已知规则(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;
    }
}

我建议尝试遵循这种模式。您最终会得到更易于重用和维护的代码。

关于c# - Java、C++ 或 C# 中的 TPIN 号码验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5866691/

相关文章:

c# - 使用 C# 从 excel 电子表格读取/写入

c++ - 重载函数不明确

C++ 最令人头疼的解析又来了

c# - Entity Framework 5 过滤并包含导航属性

c# - 如何用 `someObject.ToString()` 替换所有出现的 `Convert.ToString(someObject);`

java - 为什么我应该使用单独的线程在 JAVA 中显示 GUI

java - org.apache.jasper.JasperException : javax. servlet.ServletException : javax. servlet.jsp.JspException:无法在名称airline_name下找到bean

c++ - 如何编写可以在 msdos 上运行的 C++ 控制台 exe?

c# - 在 net.tcp wcf context 上传输用户信息

java - 从 WSDL 到 Java 对象 - 自动生成?