82 |
82 |
83 # how much redundancy is permitted, if the password is |
83 # how much redundancy is permitted, if the password is |
84 # long enough. we will skip the redudancy penalty if this |
84 # long enough. we will skip the redudancy penalty if this |
85 # number is not exceeded (meaning redundancy < this number) |
85 # number is not exceeded (meaning redundancy < this number) |
86 self.redundancy = { |
86 self.redundancy = { |
87 "value": 1, # 1 means, not double characters, default to start |
87 "value": 1, # 1 means, not double characters, |
88 "permitted": 2.0, # 2 means, in average every character can occur twice |
88 # default to start |
|
89 "permitted": 2.0, # 2 means, in average every character |
|
90 # can occur twice |
89 "status": self.Status_Failed, |
91 "status": self.Status_Failed, |
90 "rating": 0, |
92 "rating": 0, |
91 } |
93 } |
92 |
94 |
93 # number of uppercase letters, such as A-Z |
95 # number of uppercase letters, such as A-Z |
314 uniqueCharacters.append(password[index1]) |
316 uniqueCharacters.append(password[index1]) |
315 |
317 |
316 # calculate a redundancy number |
318 # calculate a redundancy number |
317 self.redundancy["value"] = len(password) / len(uniqueCharacters) |
319 self.redundancy["value"] = len(password) / len(uniqueCharacters) |
318 |
320 |
319 # Check for sequential alpha string patterns (forward and reverse) but only, |
321 # Check for sequential alpha string patterns (forward and reverse) |
320 # if the string has already a length to check for, does not make sense to check |
322 # but only, if the string has already a length to check for, does |
321 # the password "ab" for the sequential data "abc" |
323 # not make sense to check the password "ab" for the sequential data |
|
324 # "abc" |
322 lowercasedPassword = password.lower() |
325 lowercasedPassword = password.lower() |
323 |
326 |
324 if self.passwordLength["count"] >= self.sequentialLetters["length"]: |
327 if self.passwordLength["count"] >= self.sequentialLetters["length"]: |
325 for index in range(len(self.sequentialLetters["data"]) - \ |
328 for index in range(len(self.sequentialLetters["data"]) - \ |
326 self.sequentialLetters["length"] + 1): |
329 self.sequentialLetters["length"] + 1): |
346 |
349 |
347 # Check common keyboard patterns |
350 # Check common keyboard patterns |
348 patternsMatched = [] |
351 patternsMatched = [] |
349 if self.passwordLength["count"] >= self.keyboardPatterns["length"]: |
352 if self.passwordLength["count"] >= self.keyboardPatterns["length"]: |
350 for pattern in self.keyboardPatterns["data"]: |
353 for pattern in self.keyboardPatterns["data"]: |
351 for index in range(len(pattern) - self.keyboardPatterns["length"] + 1): |
354 for index in range( |
352 fwd = pattern[index:index + self.keyboardPatterns["length"]] |
355 len(pattern) - self.keyboardPatterns["length"] + 1): |
|
356 fwd = pattern[index:index + |
|
357 self.keyboardPatterns["length"]] |
353 rev = self.__strReverse(fwd) |
358 rev = self.__strReverse(fwd) |
354 if lowercasedPassword.find(fwd) != -1: |
359 if lowercasedPassword.find(fwd) != -1: |
355 if fwd not in patternsMatched: |
360 if fwd not in patternsMatched: |
356 self.keyboardPatterns["count"] += 1 |
361 self.keyboardPatterns["count"] += 1 |
357 patternsMatched.append(fwd) |
362 patternsMatched.append(fwd) |
362 |
367 |
363 # Try to find repeated sequences of characters. |
368 # Try to find repeated sequences of characters. |
364 if self.passwordLength["count"] >= self.repeatedSequences["length"]: |
369 if self.passwordLength["count"] >= self.repeatedSequences["length"]: |
365 for index in range(len(lowercasedPassword) - \ |
370 for index in range(len(lowercasedPassword) - \ |
366 self.repeatedSequences["length"] + 1): |
371 self.repeatedSequences["length"] + 1): |
367 fwd = lowercasedPassword[index:index + self.repeatedSequences["length"]] |
372 fwd = lowercasedPassword[ |
|
373 index:index + self.repeatedSequences["length"]] |
368 if lowercasedPassword.find( |
374 if lowercasedPassword.find( |
369 fwd, index + self.repeatedSequences["length"]) != -1: |
375 fwd, index + self.repeatedSequences["length"]) != -1: |
370 self.repeatedSequences["count"] += 1 |
376 self.repeatedSequences["count"] += 1 |
371 |
377 |
372 # Try to find mirrored sequences of characters. |
378 # Try to find mirrored sequences of characters. |
373 if self.passwordLength["count"] >= self.mirroredSequences["length"]: |
379 if self.passwordLength["count"] >= self.mirroredSequences["length"]: |
374 for index in range(len(lowercasedPassword) - \ |
380 for index in range(len(lowercasedPassword) - \ |
375 self.mirroredSequences["length"] + 1): |
381 self.mirroredSequences["length"] + 1): |
376 fwd = lowercasedPassword[index:index + self.mirroredSequences["length"]] |
382 fwd = lowercasedPassword[ |
|
383 index:index + self.mirroredSequences["length"]] |
377 rev = self.__strReverse(fwd) |
384 rev = self.__strReverse(fwd) |
378 if lowercasedPassword.find( |
385 if lowercasedPassword.find( |
379 fwd, index + self.mirroredSequences["length"]) != -1: |
386 fwd, index + self.mirroredSequences["length"]) != -1: |
380 self.mirroredSequences["count"] += 1 |
387 self.mirroredSequences["count"] += 1 |
381 |
388 |
382 # Initial score based on length |
389 # Initial score based on length |
383 self.score["count"] = self.passwordLength["count"] * self.passwordLength["factor"] |
390 self.score["count"] = self.passwordLength["count"] * \ |
|
391 self.passwordLength["factor"] |
384 |
392 |
385 # passwordLength |
393 # passwordLength |
386 # credit additional length or punish "under" length |
394 # credit additional length or punish "under" length |
387 if self.passwordLength["count"] >= self.passwordLength["minimum"]: |
395 if self.passwordLength["count"] >= self.passwordLength["minimum"]: |
388 # credit additional characters over minimum |
396 # credit additional characters over minimum |
389 self.passwordLength["rating"] = self.passwordLength["bonus"] + \ |
397 self.passwordLength["rating"] = self.passwordLength["bonus"] + \ |
390 (self.passwordLength["count"] - self.passwordLength["minimum"]) * \ |
398 (self.passwordLength["count"] - |
|
399 self.passwordLength["minimum"]) * \ |
391 self.passwordLength["factor"] |
400 self.passwordLength["factor"] |
392 else: |
401 else: |
393 self.passwordLength["rating"] = self.passwordLength["penalty"] |
402 self.passwordLength["rating"] = self.passwordLength["penalty"] |
394 self.score["count"] += self.passwordLength["rating"] |
403 self.score["count"] += self.passwordLength["rating"] |
395 |
404 |
396 # recommendedPasswordLength |
405 # recommendedPasswordLength |
397 # Credit reaching the recommended password length or put a |
406 # Credit reaching the recommended password length or put a |
398 # penalty on it |
407 # penalty on it |
399 if self.passwordLength["count"] >= self.recommendedPasswordLength["minimum"]: |
408 if self.passwordLength["count"] >= \ |
|
409 self.recommendedPasswordLength["minimum"]: |
400 self.recommendedPasswordLength["rating"] = \ |
410 self.recommendedPasswordLength["rating"] = \ |
401 self.recommendedPasswordLength["bonus"] + \ |
411 self.recommendedPasswordLength["bonus"] + \ |
402 (self.passwordLength["count"] - \ |
412 (self.passwordLength["count"] - \ |
403 self.recommendedPasswordLength["minimum"]) * \ |
413 self.recommendedPasswordLength["minimum"]) * \ |
404 self.recommendedPasswordLength["factor"] |
414 self.recommendedPasswordLength["factor"] |
408 self.score["count"] += self.recommendedPasswordLength["rating"] |
418 self.score["count"] += self.recommendedPasswordLength["rating"] |
409 |
419 |
410 # lowercaseLetters |
420 # lowercaseLetters |
411 # Honor or punish the lowercase letter use |
421 # Honor or punish the lowercase letter use |
412 if self.lowercaseLetters["count"] > 0: |
422 if self.lowercaseLetters["count"] > 0: |
413 self.lowercaseLetters["rating"] = self.lowercaseLetters["bonus"] + \ |
423 self.lowercaseLetters["rating"] = \ |
414 self.lowercaseLetters["count"] * self.lowercaseLetters["factor"] |
424 self.lowercaseLetters["bonus"] + \ |
|
425 self.lowercaseLetters["count"] * \ |
|
426 self.lowercaseLetters["factor"] |
415 else: |
427 else: |
416 self.lowercaseLetters["rating"] = self.lowercaseLetters["penalty"] |
428 self.lowercaseLetters["rating"] = self.lowercaseLetters["penalty"] |
417 self.score["count"] += self.lowercaseLetters["rating"] |
429 self.score["count"] += self.lowercaseLetters["rating"] |
418 |
430 |
419 # uppercaseLetters |
431 # uppercaseLetters |
420 # Honor or punish the lowercase letter use |
432 # Honor or punish the lowercase letter use |
421 if self.uppercaseLetters["count"] > 0: |
433 if self.uppercaseLetters["count"] > 0: |
422 self.uppercaseLetters["rating"] = self.uppercaseLetters["bonus"] + \ |
434 self.uppercaseLetters["rating"] = \ |
423 self.uppercaseLetters["count"] * self.uppercaseLetters["factor"] |
435 self.uppercaseLetters["bonus"] + \ |
|
436 self.uppercaseLetters["count"] * \ |
|
437 self.uppercaseLetters["factor"] |
424 else: |
438 else: |
425 self.uppercaseLetters["rating"] = self.uppercaseLetters["penalty"] |
439 self.uppercaseLetters["rating"] = self.uppercaseLetters["penalty"] |
426 self.score["count"] += self.uppercaseLetters["rating"] |
440 self.score["count"] += self.uppercaseLetters["rating"] |
427 |
441 |
428 # numerics |
442 # numerics |
462 self.score["count"] += self.middleNumerics["rating"] |
476 self.score["count"] += self.middleNumerics["rating"] |
463 |
477 |
464 # sequentialLetters |
478 # sequentialLetters |
465 # Honor or punish the sequential letter use |
479 # Honor or punish the sequential letter use |
466 if self.sequentialLetters["count"] == 0: |
480 if self.sequentialLetters["count"] == 0: |
467 self.sequentialLetters["rating"] = self.sequentialLetters["bonus"] + \ |
481 self.sequentialLetters["rating"] = \ |
468 self.sequentialLetters["count"] * self.sequentialLetters["factor"] |
482 self.sequentialLetters["bonus"] + \ |
469 else: |
483 self.sequentialLetters["count"] * \ |
470 self.sequentialLetters["rating"] = self.sequentialLetters["penalty"] |
484 self.sequentialLetters["factor"] |
|
485 else: |
|
486 self.sequentialLetters["rating"] = \ |
|
487 self.sequentialLetters["penalty"] |
471 self.score["count"] += self.sequentialLetters["rating"] |
488 self.score["count"] += self.sequentialLetters["rating"] |
472 |
489 |
473 # sequentialNumerics |
490 # sequentialNumerics |
474 # Honor or punish the sequential numerics use |
491 # Honor or punish the sequential numerics use |
475 if self.sequentialNumerics["count"] == 0: |
492 if self.sequentialNumerics["count"] == 0: |
476 self.sequentialNumerics["rating"] = self.sequentialNumerics["bonus"] + \ |
493 self.sequentialNumerics["rating"] = \ |
477 self.sequentialNumerics["count"] * self.sequentialNumerics["factor"] |
494 self.sequentialNumerics["bonus"] + \ |
478 else: |
495 self.sequentialNumerics["count"] * \ |
479 self.sequentialNumerics["rating"] = self.sequentialNumerics["penalty"] |
496 self.sequentialNumerics["factor"] |
|
497 else: |
|
498 self.sequentialNumerics["rating"] = \ |
|
499 self.sequentialNumerics["penalty"] |
480 self.score["count"] += self.sequentialNumerics["rating"] |
500 self.score["count"] += self.sequentialNumerics["rating"] |
481 |
501 |
482 # keyboardPatterns |
502 # keyboardPatterns |
483 # Honor or punish the keyboard patterns use |
503 # Honor or punish the keyboard patterns use |
484 if self.keyboardPatterns["count"] == 0: |
504 if self.keyboardPatterns["count"] == 0: |
485 self.keyboardPatterns["rating"] = self.keyboardPatterns["bonus"] + \ |
505 self.keyboardPatterns["rating"] = \ |
486 self.keyboardPatterns["count"] * self.keyboardPatterns["factor"] |
506 self.keyboardPatterns["bonus"] + \ |
|
507 self.keyboardPatterns["count"] * \ |
|
508 self.keyboardPatterns["factor"] |
487 else: |
509 else: |
488 self.keyboardPatterns["rating"] = self.keyboardPatterns["penalty"] |
510 self.keyboardPatterns["rating"] = self.keyboardPatterns["penalty"] |
489 self.score["count"] += self.keyboardPatterns["rating"] |
511 self.score["count"] += self.keyboardPatterns["rating"] |
490 |
512 |
491 # Count our basicRequirements and set the status |
513 # Count our basicRequirements and set the status |
526 # requirement met |
548 # requirement met |
527 self.basicRequirements["count"] += 1 |
549 self.basicRequirements["count"] += 1 |
528 |
550 |
529 # judge the requirement status |
551 # judge the requirement status |
530 self.basicRequirements["status"] = self.__determineStatus( |
552 self.basicRequirements["status"] = self.__determineStatus( |
531 self.basicRequirements["count"] - self.basicRequirements["minimum"]) |
553 self.basicRequirements["count"] - |
|
554 self.basicRequirements["minimum"]) |
532 if self.basicRequirements["status"] != self.Status_Failed: |
555 if self.basicRequirements["status"] != self.Status_Failed: |
533 self.basicRequirements["rating"] = \ |
556 self.basicRequirements["rating"] = \ |
534 self.basicRequirements["bonus"] + \ |
557 self.basicRequirements["bonus"] + \ |
535 self.basicRequirements["factor"] * self.basicRequirements["count"] |
558 self.basicRequirements["factor"] * \ |
536 else: |
559 self.basicRequirements["count"] |
537 self.basicRequirements["rating"] = self.basicRequirements["penalty"] |
560 else: |
|
561 self.basicRequirements["rating"] = \ |
|
562 self.basicRequirements["penalty"] |
538 self.score["count"] += self.basicRequirements["rating"] |
563 self.score["count"] += self.basicRequirements["rating"] |
539 |
564 |
540 # beyond basic requirements |
565 # beyond basic requirements |
541 self.recommendedPasswordLength["status"] = self.__determineStatus( |
566 self.recommendedPasswordLength["status"] = self.__determineStatus( |
542 self.recommendedPasswordLength["count"] - \ |
567 self.recommendedPasswordLength["count"] - \ |
561 # we apply them only, if the length is not awesome |
586 # we apply them only, if the length is not awesome |
562 if self.recommendedPasswordLength["status"] != self.Status_Exceeded: |
587 if self.recommendedPasswordLength["status"] != self.Status_Exceeded: |
563 # repeatedSequences |
588 # repeatedSequences |
564 # Honor or punish the use of repeated sequences |
589 # Honor or punish the use of repeated sequences |
565 if self.repeatedSequences["count"] == 0: |
590 if self.repeatedSequences["count"] == 0: |
566 self.repeatedSequences["rating"] = self.repeatedSequences["bonus"] |
591 self.repeatedSequences["rating"] = \ |
|
592 self.repeatedSequences["bonus"] |
567 else: |
593 else: |
568 self.repeatedSequences["rating"] = self.repeatedSequences["penalty"] + \ |
594 self.repeatedSequences["rating"] = \ |
|
595 self.repeatedSequences["penalty"] + \ |
569 self.repeatedSequences["count"] * \ |
596 self.repeatedSequences["count"] * \ |
570 self.repeatedSequences["factor"] |
597 self.repeatedSequences["factor"] |
571 |
598 |
572 # mirroredSequences |
599 # mirroredSequences |
573 # Honor or punish the use of mirrored sequences |
600 # Honor or punish the use of mirrored sequences |
574 if self.mirroredSequences["count"] == 0: |
601 if self.mirroredSequences["count"] == 0: |
575 self.mirroredSequences["rating"] = self.mirroredSequences["bonus"] |
602 self.mirroredSequences["rating"] = \ |
|
603 self.mirroredSequences["bonus"] |
576 else: |
604 else: |
577 self.mirroredSequences["rating"] = self.mirroredSequences["penalty"] + \ |
605 self.mirroredSequences["rating"] = \ |
|
606 self.mirroredSequences["penalty"] + \ |
578 self.mirroredSequences["count"] * \ |
607 self.mirroredSequences["count"] * \ |
579 self.mirroredSequences["factor"] |
608 self.mirroredSequences["factor"] |
580 |
609 |
581 # save value before redundancy |
610 # save value before redundancy |
582 self.score["beforeRedundancy"] = self.score["count"] |
611 self.score["beforeRedundancy"] = self.score["count"] |
583 |
612 |
584 # apply the redundancy |
613 # apply the redundancy |
585 # is the password length requirement fulfilled? |
614 # is the password length requirement fulfilled? |
586 if self.recommendedPasswordLength["status"] != self.Status_Exceeded: |
615 if self.recommendedPasswordLength["status"] != self.Status_Exceeded: |
587 # full penalty, because password is not long enough, only for a positive score |
616 # full penalty, because password is not long enough, only for |
|
617 # a positive score |
588 if self.score["count"] > 0: |
618 if self.score["count"] > 0: |
589 self.score["count"] *= 1.0 / self.redundancy["value"] |
619 self.score["count"] *= 1.0 / self.redundancy["value"] |
590 |
620 |
591 # level it out |
621 # level it out |
592 if self.score["count"] > 100: |
622 if self.score["count"] > 100: |