Python 读写IC卡、复制IC卡
本示例使用的发卡器:https://item.taobao.com/item.htm?spm=a1z10.5-c.w4002-17663462238.11.3614789e318TMs&id=615391857885https://item.taobao.com/item.htm?spm=a1z10.5-c.w4002-17663462238.11.3614789e318TMs&id=615391857885
#python通过缩进来表示代码块,不可以随意更改每行前面的空白,否则程序会运行错误!!!如果缩进不一致,就会报错: IndentationError
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#python -m pdb xxx.py 调试程度 n命令单步执行,s命令单步执行 会进入函数内部 b xx ,c
#import pdb pdb.set_trace() 设断点import ctypes #调用DLL动态库要有这个引用
import sys
import os
import struct #struct的pack函数把任意数据类型变成字符串
import pdb #引入程序调试功能,可用 pdb.set_trace() 设置程序调试断点#IC卡操作错误代码解释
def PrintErrInf(Errcode):if(Errcode==8):print('错误代码:8,未寻到卡,请重新拿开卡后再放到感应区!')elif(Errcode==1):print('错误代码:1,0~2块都没读出来,可能刷卡太块。但卡序列号已被读出来!')elif(Errcode==2):print('错误代码:2,第0块已被读出,但1~2块读取失败。卡序列号已被读出来!')elif(Errcode==3): print('错误代码:3,第0、1块已被读出,但2块读取失败。卡序列号已被读出来!')elif(Errcode==9):print('错误代码:9,有多张卡在感应区,寻卡过程中防冲突失败,读序列吗错误!')elif(Errcode==10):print('错误代码:10,该卡可能已被休眠,无法选中卡片!')elif(Errcode==11):print('错误代码:11,密码装载失败!') elif(Errcode==12):print('错误代码:12,卡片密码认证失败!')elif(Errcode==13):print('错误代码:13,读本块失败,原因是刷卡太快或本块所对应的区还没通过密码认证!')elif(Errcode==14):print('错误代码:14,写本块失败,原因是刷卡太快或本块所对应的区还没通过密码认证!')elif(Errcode==21):print('错误代码:21,没有动态库!')elif(Errcode==22):print('错误代码:22,动态库或驱动程序异常!')elif(Errcode==23):print('错误代码:23,驱动程序错误或尚未安装!')elif(Errcode==24):print('错误代码:24,操作超时,一般是动态库没有反映!')elif(Errcode==25):print('错误代码:25,发送字数不够!')elif(Errcode==26):print('错误代码:26,发送的CRC错!')elif(Errcode==27):print('错误代码:27,接收的字数不够!')elif(Errcode==28):print('错误代码:28,接收的CRC错!')else:print('未知错误,错误代码:'+str(status))#加载当前目录下的DLL
dllfile=sys.path[0]+'\OUR_MIFARE.dll'
Objdll = ctypes.windll.LoadLibrary(dllfile)
Objdll = ctypes.WinDLL(dllfile)#控制字定义
BLOCK0_EN=eval('0x01') #读写块0
BLOCK1_EN=eval('0x02') #读写块1
BLOCK2_EN=eval('0x04') #读写块2
NEEDSERIAL=eval('0x08') #读写指定序列号的卡
EXTERNKEY=eval('0x10') #需要每次指定密码
NEEDHALT=eval('0x20') #写卡后是否休眠卡#根据入口参数执行不同功能
if(len(sys.argv)>1): if(str(sys.argv[1])=='0'): #驱动读写器发出响声Objdll.pcdbeep(50)print('驱动读卡器嘀一声!')elif(str(sys.argv[1])=='1'): #读取设备的出厂编号devno=bytes(4) #声明4个字节缓冲status=Objdll.pcdgetdevicenumber(devno) % 256if(status==0):Objdll.pcdbeep(38)SerialNum=''for num in range(0,len(devno)):SerialNum=SerialNum+'%02x' % (devno[num])if(num<len(devno)-1):SerialNum=SerialNum+'-'print('设备出厂编号:'+ SerialNum)else:print('读取设备编号失败,错误代码:'+str(status))elif(str(sys.argv[1])=='2'): #轻松读取卡内某扇区3个块共48个字节数据myctrlword=BLOCK0_EN + BLOCK1_EN + BLOCK2_EN + EXTERNKEY #读写控制字myareano=8 #指定读写区号为第8区authmode=1 #大于0表示用A密码认证,推荐用A密码认证mypicckey=bytes([eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF')]) #卡片认证密码,16进制mypiccserial=bytes(4) #4字节卡序列号缓冲mypiccdata=bytes(48) #读卡数据缓冲,一个扇区共48个字节status = Objdll.piccreadex(myctrlword, mypiccserial, myareano, authmode, mypicckey, mypiccdata) % 256if(status==0):Objdll.pcdbeep(38)Cardno=mypiccserial[0]Cardno=Cardno+(mypiccserial[1]*256)Cardno=Cardno+(mypiccserial[2]*65536)Cardno=Cardno+(mypiccserial[3]*16777216)CardnoStr='%010d' % Cardnoprint('10进制卡号:'+CardnoStr)piccdataStr=''for num in range(0,len(mypiccdata)):piccdataStr=piccdataStr+'%02x ' % (mypiccdata[num])print('卡内数据:'+ piccdataStr)else:PrintErrInf(status)elif(str(sys.argv[1])=='3'): #轻松改写卡内某扇区3个块共48个字节数据myctrlword=BLOCK0_EN + BLOCK1_EN + BLOCK2_EN + EXTERNKEY #读写控制字myareano=8 #指定读写区号为第8区authmode=1 #大于0表示用A密码认证,推荐用A密码认证mypicckey=bytes([eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF')]) #卡片认证密码,16进制mypiccserial=bytes(4) #4字节卡序列号缓冲#mypiccdata=bytes([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47]) #写入卡片内数据,一个扇区最多写入48个字节#如果要写字符串等信息,将字符串转成字节数组写入Writeinf='伟大的中华人民共和国万岁!2020-weidadezhonhuarenmingongheguowangshi'Writeinf=Writeinf[0:48] #一个扇区最多写48个字节mypiccdata=bytes(Writeinf, encoding='gbk') #将要写入的信息转bytesstatus = Objdll.piccwriteex(myctrlword, mypiccserial, myareano, authmode, mypicckey, mypiccdata) % 256if(status==0):Objdll.pcdbeep(38)print('16进制卡号:%02x%02x%02x%02x,写卡成功!' % (mypiccserial[0],mypiccserial[1],mypiccserial[2],mypiccserial[3]))else:PrintErrInf(status)elif(str(sys.argv[1])=='4'): #修改卡片的A密码+控制字+B密码myctrlword=BLOCK0_EN + BLOCK1_EN + BLOCK2_EN + EXTERNKEY #读写控制字myareano=8 #指定读写区号为第8区authmode=1 #大于0表示用A密码认证,推荐用A密码认证mypiccoldkey=bytes([eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF')]) #卡片认证密码,16进制#mypiccnewkey 指定6字节新A密码+4字节控制码+6字节B密码+1字节功能码 ,注意:指定新密码时一定要记住,否则有可能找不回密码,导致该卡报废!!!#功能码为:3 表示同时更改A、B 密码及权限访问字#功能码为:2 表示密码权限访问字不更改,只改A、B密码#功能码为:0 示只改A密码mypiccnewkey=bytes([eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0x07'),eval('0x80'),eval('0x69'),eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0x03')])mypiccserial=bytes(4) #4字节卡序列号缓冲status = Objdll.piccchangesinglekeyex(myctrlword, mypiccserial, myareano, authmode, mypiccoldkey, mypiccnewkey) % 256if(status==0):Objdll.pcdbeep(38)print('16进制卡号:%02x%02x%02x%02x,更改卡密码成功!' % (mypiccserial[0],mypiccserial[1],mypiccserial[2],mypiccserial[3]))else:PrintErrInf(status)elif(str(sys.argv[1])=='5'): #读取某块共16个字节数据myareano=8 #指定读写区号为第8区myblock=myareano*4+0 #块号为区号*4+0、1、2、3,其中第3块为密码控制块,authmode=1 #大于0表示用A密码认证,推荐用A密码认证mypicckey=bytes([eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF')]) #卡片认证密码,16进制mypiccserial=bytes(4) #4字节卡序列号缓冲myblockdata=bytes(16) #读卡数据缓冲,一个块共16个字节status = Objdll.piccrequest(mypiccserial) % 256 #寻找感应区内的卡片if(status==0):status = Objdll.piccauthkey1(mypiccserial,myareano,authmode,mypicckey) % 256 #寻到卡后,认证要读块所在扇区的密码if(status==0):status = Objdll.piccread(myblock,myblockdata) % 256 #密码认证成功,读块数据if(status==0):Objdll.pcdbeep(38)ReadInf=''for num in range(0,len(myblockdata)):ReadInf=ReadInf+'%02x ' % (myblockdata[num])print('卡号:%02x%02x%02x%02x,读块数据成功!' % (mypiccserial[0],mypiccserial[1],mypiccserial[2],mypiccserial[3]))print('块内16进制数据:'+ReadInf)else:PrintErrInf(status)else:PrintErrInf(status)else:PrintErrInf(status)elif(str(sys.argv[1])=='6'): #写取某块共16个字节数据myareano=8 #指定写区号为第8区blockid=0 #指定写块号0、1、2、3,其中第3块为密码控制块,如改写第三块要确定写入的数据正确否这个扇区将报废!!!myblock=myareano*4+blockid #块地址=扇区号*4+块号authmode=1 #大于0表示用A密码认证,推荐用A密码认证mypicckey=bytes([eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF')]) #卡片认证密码,16进制mypiccserial=bytes(4) #4字节卡序列号缓冲if(blockid<3):myblockdata=bytes([0,1,2,3,4,5,6,7,8,9,10,11,12,13,15,15]) #写卡数据缓冲,一个块共16个字节else:#改写第3块是修改卡密码及控制字,修改前要确定数据是否正确,修改后要记住改写的密码!否则报废此扇区!!!以下信息表示改A\B密码:FFFFFFFFFFFF,不改控制位myblockdata=bytes([255,255,255,255,255,255,eval('0xFF'),eval('0x07'),eval('0x80'),eval('0x69'),255,255,255,255,255,255]) status = Objdll.piccrequest(mypiccserial) % 256 #寻找感应区内的卡片if(status==0):status = Objdll.piccauthkey1(mypiccserial,myareano,authmode,mypicckey) % 256 #寻到卡后,认证要读块所在扇区的密码if(status==0):status = Objdll.piccwrite(myblock,myblockdata) % 256 #密码认证成功,写块数据if(status==0):Objdll.pcdbeep(38)print('卡号:%02x%02x%02x%02x,写块数据成功!' % (mypiccserial[0],mypiccserial[1],mypiccserial[2],mypiccserial[3]))else:PrintErrInf(status)else:PrintErrInf(status)else:PrintErrInf(status)elif(str(sys.argv[1])=='7'): #写UID卡0区0块卡号myctrlword=BLOCK0_EN #读写控制字authmode=0 #大于0表示用A密码认证,推荐用A密码认证mypicckey=bytes([eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF')]) #卡片认证密码,16进制mypiccserial=bytes(4) #4字节卡序列号缓冲mypiccdata=bytes(16) #16字节写入数据缓冲,UID卡号是前面4个字节,第五字节必须等于前四个字节的异或和mypiccdata=struct.pack('<I',1234567890) #将卡号转字节数组低位在前status=Objdll.piccwriteserial(myctrlword,mypiccserial,authmode,mypicckey,mypiccdata) % 256 if(status==0):status = Objdll.piccrequest(mypiccserial) % 256 #寻找感应区内的卡片if(status==0):Objdll.pcdbeep(38)Cardno=mypiccserial[0]Cardno=Cardno+(mypiccserial[1]*256)Cardno=Cardno+(mypiccserial[2]*65536)Cardno=Cardno+(mypiccserial[3]*16777216)print('写10进制卡号:%010d 成功!' % Cardno)else:PrintErrInf(status)else:PrintErrInf(status)else:print('请加入正确的参数运行程序')
else:print('\n')print('请加以下参数运行程序:')print('参数 0 驱动读卡器嘀一声')print('参数 1 读4个字节设备编号')print('参数 2 读取某扇区3个块共48个字节卡内数据')print('参数 3 改写某扇区3个块共48个字节数据')print('参数 4 修改卡片密码及控制位')print('参数 5 读取某块16个字节数据')print('参数 6 改写某块16个字节数据')print('参数 7 写UID卡0区0块卡号')sys.exit()
Python 读写IC卡、复制IC卡相关推荐
- [转载] ID卡复制教程(使用T5577卡复制4100卡)
[转载] ID卡复制教程(使用T5577卡复制4100卡) 转载自:https://blog.csdn.net/TonnyBrown/article/details/75200601 ID卡的常见类型 ...
- 真正可用的使用T5577卡复制4100卡_ID卡复制
真正可用的"使用T5577卡复制4100卡"_ID卡复制操作流程 先说一下参考过的文档 实际复制卡的过程 硬件(模块) 软件 接线 开始学习帮助/说明文档 实际动手 先说一下参考过 ...
- [转载] 真正可用的使用T5577卡复制4100卡_ID卡复制操作流程
[转载] 真正可用的"使用T5577卡复制4100卡"_ID卡复制操作流程 转载自:https://blog.csdn.net/yvhkfnfhvk/article/details ...
- ID卡复制教程(使用T5577卡复制4100卡)
1 ID卡的常见类型与区别 国内常见的普通ID卡多为EM 4100 或 EM 4102卡,其特点是不可修改ID号.为了复制普通ID卡,通常采用T5577 或 EM4305卡(俗称ID白卡),其特点是内 ...
- Delphi 复制IC卡写UID卡0区0块
本示例使用的发卡器:https://item.taobao.com/item.htm?spm=a1z10.5-c.w4002-17663462238.11.7154789eKODONP&id= ...
- PN532模块复制IC加密卡
PN532模块复制IC加密卡 忍受够了每天都需要带着各种各样的卡片,如果可以将卡复制进手机里,那我就可以只带着手机,每天出门都是轻装上阵. 只要你的手机拥有nfc功能,那你可以直接将卡模拟进手机里,当 ...
- 学习使用PN532来复制IC门禁卡
学习使用PN532来复制IC门禁卡 PN532简介 PN532模块 使用前准备 硬件接线 软件设置 读取数据 写入数据 写入完成 总结 原文链接:学习使用PN532来复制IC门禁卡 PN532简介 P ...
- ic卡复制软件_使用MCT复制IC卡0扇区的方法(适用于NFC手机复制或模拟门禁卡)...
部分IC卡无法被手机门禁卡模拟功能直接添加,但可使用CUID空白卡提取门禁卡0扇区数据直接使用,或提取并转储进CUID空白卡后再行模拟到手机内,实现"曲线救国". 1.自行下载手机 ...
- ID|IC|CPU卡|国密卡|二代证|防复制门禁一体机门禁读卡器带触摸键盘(不带二维码)选型必备
一张表带你了解IC卡.ID卡.CPU卡.二代证.防复制卡各类型韦根26.韦根34.网络通信的门禁一体机的性能参数与差异,让我们在门禁设备选型方面能快速匹配到自己需要的相关设备. 普通IC卡 HX86K ...
- IC卡、ID卡及车库蓝牙卡的复制说明!(小区的门禁系统)
随着科技的发展,各种新的技术也不断的出现,如现在很多的小区物业管理和其它一些关于关卡出入的管理方面都采取了门禁卡的形式,若是门禁卡丢失了,那么可能会被物业管理公司几倍的罚款,为了避免这种情况的出现,或 ...
最新文章
- GOF23设计模式(创建型模式)单例模式
- NFS企业级网络文件共享
- 使用jQuery的hover事件在IE中不停闪动的解决方法
- c++五子棋_Java五子棋实现
- onclick 传参,用转义符进行转义。
- MBR与GPT的区别
- js请求结果拦截机器_CefSharp请求资源拦截及自定义处理
- java文件流操作注意
- Python笔记-Flask的搭建及基本使用
- 【html xml】gt; 大于 lt; 小于
- python爬虫抖音音浪_【Python爬虫】抖音去水印
- 五一新闻回顾:XP SP3悄发布 微软雅虎终谈崩
- 2021-2025年中国成人脊柱矫形器行业市场供需与战略研究报告
- 页游中的十大经典游戏题材
- 说到建模,如果不提这几个软件的话……
- 2022年强网杯rcefile wp
- 山东科技大学计算机篮球,山东科技大学第十七届学生男子篮球赛开幕
- 传感器的使用(一)-火焰传感器
- Pandas requires version ‘2.0.1‘ or newer of ‘xlrd‘ (version ‘1.2.0‘ currently installed).
- Android学习-使用WebView在app上显示网页