#!/usr/bin/python3 # =================================================================== # Enigma machine simulation and a GUI # =================================================================== from enigma_gui import enigma_gui from EnigmaConfig import EnigmaConfig from EnigmaMachine import EnigmaMachine import PySimpleGUI as sg import os import re import sys # ------------------------------------------------------------------- # ---- configuration # ------------------------------------------------------------------- # ---- get configuration file configfile = 'enigma_config.csv' if len(sys.argv) > 1: configfile = sys.argv[1] if not os.path.exists(configfile): print() print(f'Can not find enigma configuration file ({configfile})') print() sys.exit() # ---- create an enigma machine object em = EnigmaMachine(configfile) # ---- create a GUI window win,tsize = enigma_gui(em.config) # ------------------------------------------------------------------- # ----event loop # ------------------------------------------------------------------- # ---- alphabet to index support function def _char_to_idx(c,abc): for i in range(len(abc)): if abc[i] == c: return i return 0 lst_in = '' lst_out = '' while(True): # ---- wait on an event event,values = win.read() ##print() ##print(f'event = {event}') ##print(f'values= {values}') ##print() # ---- event: exit program if event in ('Exit',sg.WIN_CLOSED): break # ---- event: single character if len(event) == 1: if event not in em.config.abc: print() print('internal error - do not recognize event ' + f'({event}) - end program') print() sys.exit() lst_in = lst_in + event if len(lst_in) > tsize-1: win['-IN-'].update('text buffer overflow') win['-OUT-'].update('text buffer overflow') continue win['-IN-'].update(lst_in) idx_in = em.char_to_idx(event) idx_out = em.substitution(idx_in) lst_out = lst_out + em.idx_to_char(idx_out) win['-OUT-'].update(lst_out) continue # ---- event: reset rotors if event == 'Reset Rotors': lst_in = '' lst_out = '' win['-IN-'].update('') win['-OUT-'].update('') em.reset() continue # ---- set rotors if event == 'Set Rotors': lst_in = '' lst_out = '' win['-IN-'].update('') win['-OUT-'].update('') rnam = values['-RROTOR-'] rpos = values['-RPOSITION-'].upper() ridx = _char_to_idx(rpos,em.abc) mnam = values['-MROTOR-'] mpos = values['-MPOSITION-'].upper() midx = _char_to_idx(mpos,em.abc) lnam = values['-LROTOR-'] lpos = values['-LPOSITION-'].upper() lidx = _char_to_idx(lpos,em.abc) nam = [lnam,mnam,rnam] pos = [lidx,midx,ridx] em.set(nam,pos) continue # ---- event: clear encrypt/decrypt buffers if event == 'Clear Buffer': lst_in = '' lst_out = '' win['-IN-'].update('') win['-OUT-'].update('') continue # ---- event: display (enigma machine internals) if event == 'Display': em.display_internal_state() continue # ---- event: stats (enigma machine rotor info) if event == 'Stats': em.display_rotor_stats() continue # ---- event: auto advance on if event == 'Auto Advance On': em.auto_advance_on() continue # ---- event: auto advance off if event == 'Auto Advance Off': em.auto_advance_off() continue # ---- event: substitution debug on if event == 'Sub Debug On': em.sub_debug_on() continue # ---- event: substitution debug off if event == 'Sub Debug Off': em.sub_debug_off() continue win.close() print()