Last active
August 29, 2015 13:57
-
-
Save pimiento/9649073 to your computer and use it in GitHub Desktop.
Проверка на валидность логина, с тремя типами "проверялок" и тестами.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python2 | |
# -*- coding: utf-8 -*- | |
""" | |
В системе авторизации есть ограничение: | |
* логин должен начинаться с латинской буквы, | |
* состоять из латинских букв, цифр, точки и минуса, | |
* но заканчиваться только латинской буквой или цифрой; | |
* минимальная длина логина — один символ, максимальная — 20. | |
""" | |
import re | |
import unittest | |
from string import ascii_letters, digits | |
max_len = 20 | |
correct_end = ascii_letters + digits | |
correct_symbols = correct_end + "-." | |
def cchecker(login): | |
""" | |
Проверка корректности логина в цикле | |
""" | |
length_counter = max_len | |
for c in login: | |
if length_counter == max_len and c not in ascii_letters: | |
# начинается не с латинской буквы | |
return False | |
if length_counter == 0: | |
# превышена длина | |
return False | |
if c not in correct_symbols: | |
return False | |
length_counter -= 1 | |
if length_counter < max_len and c in correct_end: | |
# был хоть один символ и последний цифра или латинская буква | |
return True | |
else: | |
return False | |
def occhecker(login): | |
""" | |
Проверка корректности логина посимвольным проходом в цикле. | |
Для оптимизации используются числовые коды символов, а не поиск вида: | |
if c not in string.ascii_letters | |
Но интересный момент: получается медленнее! | |
""" | |
length_counter = max_len | |
for c in login: | |
o = ord(c) | |
if length_counter == max_len: # начинается не с латинской буквы | |
if not (o > 96 and o < 123) and \ | |
not (o > 64 and o < 91): return False | |
if length_counter == 0: return False # превышена длина | |
# not a digit | |
# not a uppercase letter | |
# not a downcase letter | |
# not a minus or dot | |
if not (o > 47 and o < 58) and \ | |
not (o > 96 and o < 123) and \ | |
not (o > 64 and o < 91) and \ | |
o != 45 and o != 46: return False | |
length_counter -= 1 | |
if length_counter < max_len: | |
o = ord(c) | |
# был хоть один символ и последний цифра или латинская буква | |
if not (o > 47 and o < 58) and \ | |
not (o > 96 and o < 123) and \ | |
not (o > 64 and o < 91): return False | |
else: return True | |
else: return False | |
def rchecker(login): | |
""" | |
Проверка корректности логина регулярным выражением | |
""" | |
return bool(re.match(r"^[a-zA-Z][a-zA-Z0-9.-]{0,18}[a-zA-Z0-9]$", login)) | |
class LoginCheckTest(unittest.TestCase): | |
correct_login = "my.hard123-login2" | |
cases = dict( | |
uncorrect_symbol = "abcоdefg123-.me", | |
first_uncorrect_symbol = "сdef--12ghe.-hey", | |
last_uncorrect_symbol = "cdef--12ghe.-heу", | |
first_num = "1my.login", | |
first_dot = ".-login123-.abc", | |
last_dot = "my-123.login.", | |
first_minus = "-login123-.abc", | |
last_minus = "my-123.login-", | |
less_than_min = "", | |
more_than_max = "a.b-1234-cd.efg--hijklm.nop56-q-r-s----tu.v" | |
) | |
def test_cycle_checker(self): | |
self.assertTrue(cchecker(self.correct_login)) | |
for name, login in self.cases.iteritems(): | |
self.assertFalse(cchecker(login)) | |
def test_regex_checker(self): | |
self.assertTrue(rchecker(self.correct_login)) | |
for login in self.cases.values(): | |
self.assertFalse(rchecker(login)) | |
def test_regex_checker(self): | |
self.assertTrue(occhecker(self.correct_login)) | |
for login in self.cases.values(): | |
self.assertFalse(occhecker(login)) | |
if __name__ == "__main__": | |
unittest.main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment