Проверка номера TPIN в java, c или c#

#c# #java #c #validation

#c# #java #c #проверка

Вопрос:

У меня есть небольшое требование для проверки 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;
}
  

Комментарии:

1. Когда дело доходит до PIN-кодов, обычно имеет смысл обращаться с ними как со строками, даже если все они числовые.

2. @ereOn: Вы правы, надоело пытаться с целыми числами

Ответ №1:

Для начала, использование 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;
    }
}
  

Я рекомендую попробовать следовать этому шаблону. В итоге вы получите код, который намного проще использовать повторно и поддерживать.

Комментарии:

1. @Groo : Осталось последнее, проверить правило № 1 .. 1. TPIN не должен располагаться последовательно.

2. @Groo: Не могли бы вы, пожалуйста, рассказать мне, как проверить последовательность цифр?

3. @Chandu: Я думал, что опубликовал достаточно, чтобы вы начали. 🙂 Хорошо, я обновлю ответ, хотя в любом случае предлагаю вам попробовать сделать это самостоятельно.

4. @Groo : Спасибо.. я отредактировал свой вопрос и добавил свой собственный ответ для проверки последовательности, дайте мне знать, если это можно улучшить 🙂

5. @Chandu: Я не эксперт по Java, но я считаю, что вам это не нужно Character.valueOf , вы можете просто написать if (tpin.charAt(i) != firstChar) return false .

Ответ №2:

Вы можете сгенерировать последовательный 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). Вы можете получить первую цифру и использовать цикл для сравнения с остальными цифрами.

Комментарии:

1. кажется, что на C это проще#