class SwipeFrame(Frame): def __init__(self, parent): super().__init__(parent) self.columnconfigure(0, weight=1) self.rowconfigure(4, weight=1) Separator(self, orient=HORIZONTAL).grid(row=0, columnspan=4, sticky=E + W, pady=5) self.swipe_field = EntryWithHintText( self, hint="Type PIN, then swipe card. If there's no PIN, just swipe.") self.swipe_field.grid(row=1, column=0, sticky=E + W) self.swipe_field.bind('<Return>', self.card_swiped) Separator(self, orient=HORIZONTAL).grid(row=2, columnspan=4, sticky=E + W, pady=5) Label(self, text='Swipe Output', anchor=CENTER).grid(row=3, columnspan=4, sticky=E + W) self.output_text = ScrolledText(self, bg='#F0F0F0', borderwidth=2, relief=GROOVE) self.output_text.config(state=DISABLED) self.output_text.grid(row=4, columnspan=4, sticky=N + E + W + S) def card_swiped(self, event=None): field_data = self.swipe_field.get() # card not swiped if "%B" not in field_data: return else: pin, data = field_data.split("%B") if data.count('?') != 2 or data.count('^') != 2: self.swipe_field.delete(len(pin), END) else: sec1, sec2, sec3 = data.split('^') if len(sec1) != 19: t1, t2, t3 = sec3.split('?') if len(t1) == 8 or len(t1) == 10: card_no = sec1[0:16] else: card_no = sec1[0] + sec3[14:16] + sec1[6:15] + sec3[16:20] else: card_no = sec1[0:20] if self.luhn_checksum(card_no) == 0: ck = '' else: ck = ' CHECKSUM FAILED - Check card numbers from this brand.' output_line = '{},{}{}\n'.format( ''.join(card_no[i:i + 4] for i in range(0, len(card_no), 4)), pin, ck) self.output_text.config(state=NORMAL) self.output_text.insert('end-1c', output_line) self.output_text.see(END) self.output_text.config(state=DISABLED) self.swipe_field.delete(0, END) @staticmethod def luhn_checksum(card_number): def digits_of(n): return [int(d) for d in str(n)] digits = digits_of(card_number) odd_digits = digits[-1::-2] even_digits = digits[-2::-2] checksum = 0 checksum += sum(odd_digits) for d in even_digits: checksum += sum(digits_of(d * 2)) return checksum % 10
class SwipeFrame(Frame): def __init__(self, parent): super().__init__(parent) self.columnconfigure(0, weight=1) self.rowconfigure(4, weight=1) Separator(self, orient=HORIZONTAL).grid(row=0, columnspan=4, sticky=E + W, pady=5) self.swipe_field = EntryWithHintText( self, hint="Type PIN, then swipe card. If there's no PIN, just swipe.") self.swipe_field.grid(row=1, column=0, sticky=E + W) self.swipe_field.bind('<Return>', self.card_swiped) Separator(self, orient=HORIZONTAL).grid(row=2, columnspan=4, sticky=E + W, pady=5) Label(self, text='Swipe Output', anchor=CENTER).grid(row=3, columnspan=4, sticky=E + W) self.output_text = ScrolledText(self, bg='#F0F0F0', borderwidth=2, relief=GROOVE) self.output_text.config(state=DISABLED) self.output_text.grid(row=4, columnspan=4, sticky=N + E + W + S) def card_swiped(self, event=None): field_data = self.swipe_field.get() # card not swiped if "%B" not in field_data: return else: pin, data = field_data.split("%B") if data.count('?') != 2 or data.count('^') != 2: self.swipe_field.delete(len(pin), END) else: sec1, sec2, sec3 = data.split('^') if len(sec1) != 19: t1, t2, t3 = sec3.split('?') if len(t1) == 8: card_no = sec1[0:16] else: card_no = sec1[0] + sec3[14:16] + sec1[6:15] + sec3[16:20] else: card_no = sec1[0:20] output_line = '{},{}\n'.format( ''.join(card_no[i:i + 4] for i in range(0, len(card_no), 4)), pin) self.output_text.config(state=NORMAL) self.output_text.insert('end-1c', output_line) self.output_text.see(END) self.output_text.config(state=DISABLED) self.swipe_field.delete(0, END)
class BarcodeFrame(Frame): def __init__(self, parent): super().__init__(parent) self.columnconfigure(1, weight=1) self.rowconfigure(4, weight=1) Separator(self, orient=HORIZONTAL).grid(row=0, columnspan=4, sticky=E+W, pady=5) self.pin_field = EntryWithHintText(self, hint='Type PIN, hit enter', width=20) self.pin_field.grid(row=1, column=0, sticky=W, padx=5) self.pin_field.bind('<Return>', self.pin_entered) self.code_field = EntryWithHintText(self, hint='Scan Barcode') self.code_field.grid(row=1, column=1, sticky=E+W) self.code_field.bind('<Return>', self.code_entered) note = " Note: If you set up your barcode scanner to prepend '%B' to scans, hitting enter after the PIN " \ "is not required." Label(self, text=note).grid(row=2, columnspan=2, sticky=S+W, pady=5) Separator(self, orient=HORIZONTAL).grid(row=3, columnspan=4, sticky=E+W, pady=5) Label(self, text='Scan Output', anchor=CENTER).grid(row=4, columnspan=4, sticky=E+W) self.output_text = ScrolledText(self, bg='#F0F0F0', borderwidth=2, relief=GROOVE) self.output_text.config(state=DISABLED) self.output_text.grid(row=5, columnspan=4, sticky=N+E+W+S) def pin_entered(self, event=None): if '%B' in self.pin_field.get(): pin, code = self.pin_field.get().split('%B') self.detect(pin, code) else: self.code_field.focus() def code_entered(self, event=None): self.detect(self.pin_field.get(), self.code_field.get()) def detect(self, pin, code): code = code.replace('%B', '') # kohl's. others? if len(code) == 30: code = code[-19:] # cabela's elif re.search("^\d{10}[a-zA-Z]{6}$", code): pin = code[-6:] code = code[:9] elif len(code) != 19 and len(code) != 16: self.code_field.delete(0, END) return output_line = '{},{}\n'.format(''.join(code[i:i+4] for i in range(0,len(code), 4)), pin) self.output_text.config(state=NORMAL) self.output_text.insert('end-1c', output_line) self.output_text.see(END) self.output_text.config(state=DISABLED) self.code_field.delete(0, END) self.pin_field.delete(0, END) self.pin_field.focus()