Python 读写IC卡、复制IC卡

article/2025/11/7 10:18:27

本示例使用的发卡器: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()


http://chatgpt.dhexx.cn/article/QpdPGqHL.shtml

相关文章

IC卡防批量复制破解 Mifare卡一卡一密方案说明 门禁卡校园卡水卡会员卡防破解方案

目前市面上大部分的IC卡&#xff08;如门禁卡&#xff0c;门锁卡&#xff0c;水卡&#xff0c;校园卡&#xff0c;会员卡等&#xff09;均属于Mifare1S50卡。该类卡片虽然在采购价格上较有优势&#xff0c;但同时也存在被批量破解、复制等安全性风险。如果更换为CPU卡&#xff…

php ic卡,IC卡的数据结构认识

讲解一下滚动码&#xff1a; 滚动码是一种防复制的技术&#xff0c;判断滚动码的方法非常的简单。 拿到物业发的原卡先解密&#xff0c;解密后数据保存。保存完成之后&#xff0c;拿着你的物业卡原卡去刷一下电梯或者门禁。然后再回来对比一下数据。看下刷电梯前的数据和刷电梯…

IC卡分类

M1 普通IC卡&#xff0c;0扇区不可以修改&#xff0c;其他扇区可反复擦写。我们日常碰到的单位食堂卡&#xff0c;小区门禁卡&#xff0c;单元的电梯卡都使用的是M1卡。 UID卡 所有区块可被重复读写 卡片ID可改写且使用后门指令更改ID 卡片ID可重复修改 相应后门指令&#xff…

使用ACR122U和Proxmark3复制IC卡

常见IC卡片介绍及使用ACR122U和Proxmark3复制卡方法 一、常见IC卡片介绍 1.1 ID卡和IC卡 ID卡&#xff1a;全称身份识别卡(Identification Card)&#xff0c;多为低频(125Khz)&#xff0c;是一种不可写入的感应卡&#xff0c;含固定的编号&#xff0c;主要有台湾SYRIS的EM格…

Delphi 复制IC卡写UID卡0区0块

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?spma1z10.5-c.w4002-17663462238.11.7154789eKODONP&id615391857885https://item.taobao.com/item.htm?spma1z10.5-c.w4002-17663462238.11.7154789eKODONP&id615391857885 unit declaredll;interf…

PN532模块复制IC加密卡

PN532模块复制IC加密卡 忍受够了每天都需要带着各种各样的卡片&#xff0c;如果可以将卡复制进手机里&#xff0c;那我就可以只带着手机&#xff0c;每天出门都是轻装上阵。 只要你的手机拥有nfc功能&#xff0c;那你可以直接将卡模拟进手机里&#xff0c;当然这样并没有完全…

IC卡、ID卡及车库蓝牙卡的复制说明!(小区的门禁系统)

随着科技的发展&#xff0c;各种新的技术也不断的出现&#xff0c;如现在很多的小区物业管理和其它一些关于关卡出入的管理方面都采取了门禁卡的形式&#xff0c;若是门禁卡丢失了&#xff0c;那么可能会被物业管理公司几倍的罚款&#xff0c;为了避免这种情况的出现&#xff0…

PyCharm 关闭 Test 功能

PyCharm自带的功能&#xff0c;检测Python文件中&#xff0c;以“test”开头的函数名&#xff0c;作为测试用例&#xff0c;导致在调试时&#xff0c;优先启动“test”函数&#xff0c;对于我们正常想调试的内容进行干扰。 如果不想使用这个功能&#xff0c;需要关闭&#xff…

scalaTest的使用

配置 修改pom.xml&#xff0c;添加以下内容 <!--依赖--> <dependency><groupId>org.scalatest</groupId><artifactId>scalatest_2.11</artifactId><version>3.0.0</version><scope>test</scope> </dependenc…

GoLang之go test测试

文章目录 GoLang之go test测试1.介绍2.函数3.测试函数格式3.1格式3.2失败示例3.3成功示例13.4成功示例23.5成功示例33.6成功实例4 4.基准函数4.1成功实例14.2成功实例24.3性能比较函数 GoLang之go test测试 1.介绍 Go语言中的测试依赖go test命令。编写测试代码和编写普通的Go…

Linux下使用Speedtest测试网速

Speedtest是用来测试网络性能的开源软件&#xff0c;在Linux下面安装Speedtest可以用来测试网络出口的上传和下载速度&#xff0c;帮助排查网络方面导致的故障。 Speedtest介绍 由于公司几个项目用户访问的时候响应较慢&#xff0c;项目本身没问题&#xff0c;服务及调用的接口…

@SpringBootTest注解进行单元测试

1、首先我们通过idea创建一个Springboot项目&#xff0c;项目目录生成后&#xff0c;默认都会带main和test目录&#xff0c;如下&#xff1a; 2、我们在test目录下创建测试类&#xff0c;正常情况下创建项目的时候会自带生成对应的测试类&#xff0c;如下&#xff1a; 此时你发…

C++Test使用入门

CTest使用入门 Parasoft Ctest 是一款自动化测试工具&#xff0c;是经广泛证明的最佳实践集成解决方案&#xff0c;它能有效提高开发团队工作效率和软件质量。 创建项目导入cpp文件生成测试用例添加桩函数运行测试用例 1.创建项目 填写项目名&#xff0c;Project type选择Em…

docker安装speedtest

平常测试网速的时候常用speedtest进行测试&#xff08;测速网 - 专业网速测试, 游戏测速, 直播测速, 5G测速, 物联网监测-SpeedTest.cn&#xff09;&#xff0c;但是网站通常测试的是带宽的速度。内网速度的测试&#xff0c;一般通过传输大文件&#xff0c;查看稳定速率来计算速…

simulinktest

Smulink Test Notebook 序Subsystem Test使用Testharness对模型进行测试------------------------分割线-------------------------------------------- 序 Simulink Test 为模型的仿真&#xff0c;测试&#xff0c;验证和代码生成提供工具&#xff1b; 它包括Test Sequence&a…

Testbench编写指南(1)基本组成与示例

对于小型设计来说&#xff0c;最好的测试方式便是使用TestBench和HDL仿真器来验证其正确性。一般TestBench需要包含这些部分&#xff1a;实例化待测试设计、使用测试向量激励设计、将结果输出到终端或波形窗口便于可视化观察、比较实际结果和预期结果。下面是一个标准的HDL验证…

Device Self-test

DST Device Self-test命令Command CompletionDevice Self-test Operations (Optional)Short Device Self-Test OperationExtended Device Self-Test Operation Device Self-test命令 Device Self-test命令用于开始一个device self-test操作&#xff0c;或者中止一个device self…

Test ignored.

项目场景&#xff1a; springboot 问题描述&#xff1a; 创建单元测试执行后控制台输出&#xff1a; Test ignored. 解决方案&#xff1a; 测试文件路径与项目文件路径不一致造成的。

Shell test命令

概述 Shell中的 test 命令用于检查某个条件是否成立&#xff0c;它可以进行数值、字符和文件三个方面的测试。 或者使用 [ ] 来判断 数值测试 #!/bin/bash num1100 num2100 if test $[num1] -eq $[num2] thenecho 两个数相等&#xff01; elseecho 两个数不相等&#xff01; …

Google Test简述

Google Test简述 Google Test 是由 Google 推出的 C 测试框架&#xff0c;具有稳定、跨平台、快速等特点&#xff0c;能够为 C 开发人员提供有效的单元测试和集成测试工具。Google Test 支持 Linux、macOS 和 Windows 操作系统&#xff0c;同时支持 gcc、clang 和 MSVC 等多种…