Created
November 10, 2016 03:55
-
-
Save rechner/61577affb285afa9faff2acbdfbf79fb to your computer and use it in GitHub Desktop.
Magtek HID reader software for python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
""" | |
Read a MagTek USB HID Swipe Reader in Linux. A description of this | |
code can be found at: http://www.micahcarrick.com/credit-card-reader-pyusb.html | |
You must be using the new PyUSB 1.0 branch and not the 0.x branch. | |
(Install with `pip install pyusb --pre` in a virtualenv. Install libusb first on debian) | |
Copyright (c) 2010 - Micah Carrick | |
With additions by Zach Sturgeon, 2016 | |
""" | |
import sys | |
import usb.core | |
import usb.util | |
VENDOR_ID = 0x0801 | |
PRODUCT_ID = 0x0002 | |
DATA_SIZE = 337 | |
# find the MagTek reader | |
device = usb.core.find(idVendor=VENDOR_ID, idProduct=PRODUCT_ID) | |
if device is None: | |
sys.exit("Could not find MagTek USB HID Swipe Reader.") | |
# make sure the hiddev kernel driver is not active | |
if device.is_kernel_driver_active(0): | |
try: | |
device.detach_kernel_driver(0) | |
except usb.core.USBError as e: | |
sys.exit("Could not detatch kernel driver: %s" % str(e)) | |
# set configuration | |
try: | |
device.set_configuration() | |
device.reset() | |
except usb.core.USBError as e: | |
sys.exit("Could not set configuration: %s" % str(e)) | |
endpoint = device[0][(0,0)][0] | |
# wait for swipe | |
data = [] | |
swiped = False | |
print "Please swipe your card..." | |
while 1: | |
try: | |
chunk = device.read(endpoint.bEndpointAddress, endpoint.wMaxPacketSize) | |
data += chunk | |
if not swiped: | |
print "Reading..." | |
swiped = True | |
if chunk.tolist() == [0,]: | |
break | |
except usb.core.USBError as e: | |
if e.args == ('Operation timed out',) and swiped: | |
if len(data) < DATA_SIZE: | |
print "Bad swipe, try again. (%d bytes)" % len(data) | |
print "Data: %s" % ''.join(map(chr, data)) | |
data = [] | |
swiped = False | |
continue | |
else: | |
break # we got it! | |
# now we have the binary data from the MagReader! | |
enc_formats = ('ISO/ABA', 'AAMVA', 'CADL', 'Blank', 'Other', 'Undetermined', 'None') | |
print "Card Encoding Type: %s" % enc_formats[data[6]] | |
print "Track 1 Decode Status: %r" % bool(not data[0]) | |
print "Track 1 Data Length: %d bytes" % data[3] | |
print "Track 1 Data: %s" % ''.join(map(chr, data[7:116])) | |
print "Track 2 Decode Status: %r" % bool(not data[1]) | |
print "Track 2 Data Length: %d bytes" % data[4] | |
print "Track 2 Data: %s" % ''.join(map(chr, data[117:226])) | |
print "Track 3 Decode Status: %r" % bool(not data[2]) | |
print "Track 3 Data Length: %d bytes" % data[5] | |
print "Track 3 Data: %s" % ''.join(map(chr, data[227:336])) | |
# since this is a bank card we can parse out the cardholder data | |
track = ''.join(map(chr, data[7:116])) | |
info = {} | |
i = track.find('^', 1) | |
info['account_number'] = track[2:i].strip() | |
j = track.find('/', i) | |
info['last_name'] = track[i+1:j].strip() | |
k = track.find('^', j) | |
info['first_name'] = track[j+1:k].strip() | |
info['exp_year'] = track[k+1:k+3] | |
info['exp_month'] = track[k+3:k+5] | |
print "Bank card info: ", info | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment