class_docstr: Each character in the Affine Cipher is encoded with the rule E(x) = (ax + b) mod m
  m is the size of the alphabet, while a and b are the keys in the cipher. a must be coprime to b.
  The Caesar cipher is a specific case of the Affine Cipher, with a=1 and b being the shift of the cipher.
  Decryption is performed by D(x) = a_inv (x - b) mod m where a_inv is the modular multiplicative inverse of a mod m.
  
  In this version of the Affine Cipher, we do not allow alphabets with several instances of the same letter in different cases.
  For instance, the alphabet 'ABCdef123' is allowed, but 'AaBbCc' is not.
class_docstr_tok: ["Each","character","in","the","Affine","Cipher","is","encoded","with","the","rule","E","(","x",")","=","(","ax","+","b",")","mod","m","m","is","the","size","of","the","alphabet",",","while","a","and","b","are","the","keys","in","the","cipher",".","a","must","be","coprime","to","b",".","The","Caesar","cipher","is","a","specific","case","of","the","Affine","Cipher",",","with","a=1","and","b","being","the","shift","of","the","cipher",".","Decryption","is","performed","by","D","(","x",")","=","a_inv","(","x","-","b",")","mod","m","where","a_inv","is","the","modular","multiplicative","inverse","of","a","mod","m.","In","this","version","of","the","Affine","Cipher",",","we","do","not","allow","alphabets","with","several","instances","of","the","same","letter","in","different","cases",".","For","instance",",","the","alphabet","'ABCdef123","'","is","allowed",",","but","'AaBbCc","'","is","not","."]
code: def decryptChar(self, char: str, a_inv: int, b: int, m: int) -> str:
      # We lower the alphabet since both ctext and alphabet need to be in the same case in order
      # to perform the shifts. The translated text will have fixed case after the translation anyways.
      # This is only necessary if the specified alphabet is uppercase.
      alphabet = [x.lower() for x in self.group]
  
      # Preserve characters that are not in alphabet
      if char not in alphabet:
          return char
      char_idx = alphabet.index(char)
      decrypted_char_idx = (a_inv * (char_idx - b)) % m
      return alphabet[decrypted_char_idx]
  
file_path: Ciphey/ciphey/basemods/Crackers/affine.py
imports: from typing import Dict, List, Optional
  import cipheycore
  import logging
  from rich.logging import RichHandler
  from ciphey.common import fix_case
  from ciphey.iface import Config, Cracker, CrackInfo, CrackResult, ParamSpec, registry
  from ciphey.mathsHelper import mathsHelper
label_desc: Use image node_id 6 for calling the Affine obj's underlying member method code with example usage: obj.decryptChar(char, a_inv, b, m) and returns: alphabet, char