我在大学项目中对TPIN验证的要求不高,但要求是,我们不应该允许用户在以下情况下设置其TPIN。

  • TPIN不应顺序排列。 (例如,升序或降序:123456、456789、987654或654321)
  • TPIN不应从零开始(例如: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#那样支持委托(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,并留给其调用方决定是否打印其描述(到控制台,消息框,网页等)。

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

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

    10-05 21:52