Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import random
- def check(lst, policy):
- if policy > 1:
- while len(lst) < 5:
- lst.insert(0, '')
- while len(lst) > 5:
- lst.pop(0) # ensure the list is always five chars long
- l1, l2, l3, l4, l5 = lst
- num_lst = [None, None, None, None, None]
- for i in range(5):
- try:
- a = int([l1, l2, l3, l4, l5][i])
- if a in (0, 1, 2, 3, 4, 5, 6, 7, 8, 9):
- num_lst[i] = 1 # test if one char is a number
- except ValueError:
- pass
- n1, n2, n3, n4, n5 = num_lst
- if policy == 5:
- if (l1.isupper() and l2.isupper() and l3.isupper() and l4.isupper() and l5.isupper()) or \
- (l1.islower() and l2.islower() and l3.islower() and l4.islower() and l5.islower()) or \
- (n1 and n2 and n3 and n4 and n5):
- return False
- elif policy == 4:
- if (l1.isupper() and l2.isupper() and l3.isupper() and l4.isupper()) or \
- (l2.isupper() and l3.isupper() and l4.isupper() and l5.isupper()) or \
- (l1.islower() and l2.islower() and l3.islower() and l4.islower()) or \
- (l2.islower() and l3.islower() and l4.islower() and l5.islower()) or \
- (n1 and n2 and n3 and n4) or (n2 and n3 and n4 and n5):
- return False
- elif policy == 3:
- if (l1.isupper() and l2.isupper() and l3.isupper()) or \
- (l2.isupper() and l3.isupper() and l4.isupper()) or \
- (l3.isupper() and l4.isupper() and l5.isupper()) or \
- (l1.islower() and l2.islower() and l3.islower()) or \
- (l2.islower() and l3.islower() and l4.islower()) or \
- (l3.islower() and l4.islower() and l5.islower()) or \
- (n1 and n2 and n3) or (n2 and n3 and n4) or (n3 and n4 and n5):
- return False
- elif policy == 2:
- if (l1.isupper() and l2.isupper()) or (l2.isupper() and l3.isupper()) or (l3.isupper() and l4.isupper()) \
- or (l4.isupper() and l5.isupper()) or (l1.islower() and l2.islower()) or \
- (l2.islower() and l3.islower()) or (l3.islower() and l4.islower()) or \
- (l4.islower() and l5.islower()) or (n1 and n2) or (n2 and n3) or (n3 and n4) or (n4 and n5):
- return False
- # compare all the symbols depending on the policy
- return True
- def keygen(key_list, custom_characters, policy, char_policy):
- letters_up, letters_low, numbers, c_chars, length, amount = key_list
- keygen_list = []
- cnt = 0 # used to determine which argument causes the error
- try:
- length = int(length)
- amount, cnt = int(amount), 1
- policy, cnt = int(policy), 2
- except (TypeError, ValueError):
- # raised if you pass anything other than an int or float
- raise Exception('Invalid argument figure: {}'.format(
- {0: length.__class__, 1: amount.__class__, 2: policy.__class__}[cnt]))
- if not letters_up and not letters_low and not numbers and not c_chars:
- raise Exception("Character arguments cannot be 0 at the same time.")
- elif (letters_up + letters_low + numbers + max(c_chars, {True: 1, False: 0}[bool(custom_characters)]) == 1)\
- and policy > 1:
- # you can't make a password that doesn't contain characters of the same type behind each other
- # with just one type
- raise Exception("For a policy greater than 1, at least 2 character types must be given.")
- elif not length or not amount:
- raise Exception("Length or amount arguments cannot be 0.")
- if letters_up:
- keygen_list.extend('ABCDEFGHIJKLMNOPQRSTUVWXYZ') # noqa
- # noqa disables code markup in PyCharm, this ^ is classified as a typo
- if letters_low:
- keygen_list.extend('abcdefghijklmnopqrstuvwxyz') # noqa
- if numbers:
- keygen_list.extend('0123456789')
- if custom_characters:
- keygen_list.extend(custom_characters)
- # if user wants a different set of custom characters, its used here
- elif c_chars:
- keygen_list.extend('#!?%&§()[]{}^<>*/+-_,;.:~@$')
- if len(keygen_list) < length and not char_policy:
- print("Insufficient characters for given length. Enabling character multi use.")
- char_policy += 1
- pswrd = [] # list that contains all final passwords, to be evaluated in another file
- for _ in range(0, amount):
- password = ''
- sym_lst = ["", "", ""] # list for all the symbols to be used in check()
- buffer_keygen_list = keygen_list.copy()
- # characters will be removed, the original list has to used for all passwords, so it can't be destroyed
- for _ in range(0, length):
- while True:
- j = random.choice(buffer_keygen_list)
- sym_lst.append(j)
- j_ = j.upper() # current char, capitalized
- k_ = sym_lst[-2].upper() # last char, capitalized
- if j_ != k_ and check(sym_lst, policy): # if they don't match, and check() is true, break loop
- if not char_policy:
- buffer_keygen_list.remove(j) # remove char
- break
- else:
- sym_lst.pop(-1) # if failed, remove last char from sym_list and try again
- while len(sym_lst) > 5:
- sym_lst.pop(0) # ensure sym_list is always 5 chars long
- password = password + j # if success, add char to password
- pswrd.append(password) # after generation of one password is finished, append to password list
- if __name__ == "__main__":
- print(password) # only print passwords if script is main script
- # I sort the passwords by strength in another file, and often generate 10.000+ passwords,
- # so printing just slows things down
- return pswrd
- if __name__ == '__main__':
- keygen([1, 1, 1, 1, 25, 10], '', 2, 0)
- # Arguments: [lettersUp, lettersLow, numbers, symbols, length, amount], 'custom characters here', policy, use characters multiple times] # noqa
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement