Source code for credsweeper.utils.hop_stat

import statistics
from typing import Tuple, Dict


[docs] class HopStat: """Statistical check distances between symbols sequence in a value on keyboard layout""" KEYBOARD = ( # "`1234567890-=", # "\0qwertyuiop[]\\", # "\0\0asdfghjkl;'", # "\0\0zxcvbnm,./", # ) TRANSLATION = str.maketrans({ '~': '`', '!': '1', '@': '2', '#': '3', '$': '4', '%': '5', '^': '6', '&': '7', '*': '8', '(': '9', ')': '0', '_': '-', '+': '=', 'Q': 'q', 'W': 'w', 'E': 'e', 'R': 'r', 'T': 't', 'Y': 'y', 'U': 'u', 'I': 'i', 'O': 'o', 'P': 'p', '{': '[', '}': ']', '|': '\\', 'A': 'a', 'S': 's', 'D': 'd', 'F': 'f', 'G': 'g', 'H': 'h', 'J': 'j', 'K': 'k', 'L': 'l', ':': ';', '"': "'", 'Z': 'z', 'X': 'x', 'C': 'c', 'V': 'v', 'B': 'b', 'N': 'n', 'M': 'm', '<': ',', '>': '.', '?': '/', }) def __init__(self): self.__hop_dict: Dict[Tuple[str, str], int] = {} base = ''.join(x for x in HopStat.KEYBOARD) for a in (x for x in base if '\0' != x): for b in (x for x in base if '\0' != x): if (b, a) in self.__hop_dict: self.__hop_dict[(a, b)] = self.__hop_dict[(b, a)] continue if a == b: self.__hop_dict[(a, b)] = 0 else: x_a, y_a, z_a = self.__get_xyz(a) x_b, y_b, z_b = self.__get_xyz(b) d = (abs(x_a - x_b) + abs(y_a - y_b) + abs(z_a - z_b)) // 2 self.__hop_dict[(a, b)] = d @staticmethod def __get_xyz(c: str) -> Tuple[int, int, int]: """Returns axial coordinates of a char on keyboad qwerty""" x = y = z = 0 for i, _ in enumerate(HopStat.KEYBOARD): x = HopStat.KEYBOARD[i].find(c) if 0 <= x: z = i x = x - (i // 2) y = -(z + x) break return x, y, z
[docs] def stat(self, value: str) -> Tuple[float, float]: """Calculates statistical distances between given symbols Args: value: string based on initial alphabet Return: Average distance, deviation or exception if a value is not in initial alphabet """ hops = [] value = value.translate(HopStat.TRANSLATION) for a, b in zip(value[:-1], value[1:]): hop = self.__hop_dict.get((a, b)) if hop is None: raise ValueError(f"Unknown char '{a}' or '{b}'") hops.append(hop) avg = statistics.mean(hops) dev = statistics.stdev(hops, avg) return avg, dev