#c# #java #c #validation
#c# #java #c #проверка
Вопрос:
У меня есть небольшое требование для проверки 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;
}
Комментарии:
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 это проще#