`
<script language="javascript">var time1;let device; // 需要连接或已连接的设备if ('hid' in navigator){}else{alert('您的浏览器不支持 Web Hid API,暂无法使用以下功能!');}navigator.hid.onconnect = function event() {console.log("hid device connected: ", event.target);}navigator.hid.ondisconnect = function event() {console.log("hid device disconnected: ", event.target);}function ParsedReturnData(databuff){var datahex="";if(databuff[0]==0x78 && databuff[1]==0x68 && databuff.length>4){switch ( databuff[3]) {case 0x0f:textarea.value="读卡器已接受响声指令!";break;case 0x1E:textarea.value="读取设备编号成功!";for (i=5;i<9;i++){datahex=datahex+databuff[i].toString(16).padStart(2, '0').toUpperCase();}serialnumber.value=datahex;break;case 0xF0:switch(databuff[4]){case 0x00:textarea.value="读取IC卡号成功!";for (i=5;i<9;i++){datahex=datahex+databuff[i].toString(16).padStart(2, '0').toUpperCase();}carduid.value=datahex;card8h10dz.value = parseInt("0x" + datahex).toString().padStart(10, '0');LHCode = datahex.substring(6, 8) + datahex.substring(4, 6) + datahex.substring(2, 4) + datahex.substring(0, 2);card8h10df.value = parseInt("0x" + LHCode).toString().padStart(10, '0');break;case 0x08:textarea.value="寻卡失败,请重新将卡片放在读卡器感应区!";break;case 0x09:textarea.value="选卡失败,此卡可能不是Mifare卡或感应区内有多张卡!";break;default:textarea.value="寻卡失败,错误代码:"+databuff[4].toString();break;}break;case 0x10:switch(databuff[4]){case 0x00:textarea.value="读取Ntag卡UID成功!";for (i=5;i<12;i++){datahex=datahex+databuff[i].toString(16).padStart(2, '0').toUpperCase();}ntaguid.value=datahex;break;case 0x08:textarea.value="寻卡失败,请重新将Ntag卡放在读卡器感应区!";break;case 0x09:textarea.value="选卡失败,此卡可能不是Ntag卡或感应区内有多张卡!";break;default:textarea.value="寻卡失败,错误代码:"+databuff[4].toString();break;}break;case 0x21:switch(databuff[4]){case 0x00:textarea.value="读取15693卡UID成功!";for (i=7;i<15;i++){datahex=datahex+databuff[i].toString(16).padStart(2, '0').toUpperCase();}uid15693.value=datahex;break;case 0x08:textarea.value="寻卡失败,请重新将15693卡放在读卡器感应区!";break;case 0x09:textarea.value="选卡失败,此卡可能不是15693卡!";break;default:textarea.value="寻卡失败,错误代码:"+databuff[4].toString();break;}break;case 0x50:switch(databuff[4]){case 0x00:textarea.value="读取二代证UID成功!";for (i=5;i<13;i++){datahex=datahex+databuff[i].toString(16).padStart(2, '0').toUpperCase();}sfzuid.value=datahex;break;case 0x08:textarea.value="寻卡失败,请重新将二代证卡放在读卡器感应区!";break;default:textarea.value="寻卡失败,错误代码:"+databuff[4].toString();break;}break;case 0x51:switch(databuff[4]){case 0x00:textarea.value="读取iCLASS卡UID成功!";for (i=5;i<13;i++){datahex=datahex+databuff[i].toString(16).padStart(2, '0').toUpperCase();}iclassuid.value=datahex;break;case 0x08:textarea.value="寻卡失败,请重新将iCLASS卡片放在读卡器感应区!";break;default:textarea.value="寻卡失败,错误代码:"+databuff[4].toString();break;}break;default:}}}async function selectdev() {try{//const devices = await navigator.hid.requestDevice({ filters: [] });//if (devices.length == 0) {// console.log("No device selected\n\n");// return;//}const devices = await navigator.hid.requestDevice({filters: [{vendorId: 0x0801, // 根据VID进行过滤productId: 0x2011, // 根据PID进行过滤//usagePage: 0x0c, // 根据usagePage进行过滤//usage: 0x01, // 根据usage进行过滤},],});device = devices[0]; // 选择列表中第一个设备if (!device.opened) { // 检查设备是否打开 await device.open(); // 打开设备}device.oninputreport = (event) => { // 电脑接收到来自设备的消息回调console.log(event); // event中包含device、reportId、data等内容let array = new Uint8Array(event.data.buffer); // event.data.buffer就是接收到的inputreport包数据了ParsedReturnData(array); //let hexstr = "";//for (const data of array) {// hexstr += (Array(2).join(0) + data.toString(16).toUpperCase()).slice(-2) + " "; // 将字节数据转换成(XX )形式字符串//}//textarea.value += hexstr; };}catch (e){console.log(e);}}function isUIntNum(val) {var testval = /^\d+$/; // 非负整数return (testval.test(val));}function isHex(val) {var testval = /^(\d|[A-F]|[a-f])+$/; // 十六进制数判断return (testval.test(val));}function ButtonDisable() { //删除按键的 onclick 事件,防止重复执行指令 document.getElementById("butt_beep").setAttribute("onclick", null);document.getElementById("butt_getdevnum").setAttribute("onclick", null);document.getElementById("butt_piccrequest").setAttribute("onclick", null);//document.getElementById("butt_readloop").setAttribute("onclick", null);}async function beep() { //驱动发卡器响声令 if (!device?.opened) {alert("请先选择已连接的读卡器!");return;}textarea.value = "";const outputData = new Uint8Array(32);outputData[0]=0x78; outputData[1]=0x68; outputData[2]=0x04;outputData[3]=0x0f;outputData[4]=0x1e;outputData[5]=0x00;outputData[6]=0xe9;outputData[7]=0x00; await device.sendReport(0, outputData); // 发送数据,第一个参数为reportId,填0表示不使用reportId}async function getdevicenumber() { //读取发卡器唯一出厂序号,可以当加密狗使用 if (!device?.opened) {alert("请先选择已连接的读卡器!");return;}textarea.value = ""; serialnumber.value="";const outputData = new Uint8Array(32);outputData[0]=0x78; outputData[1]=0x68; outputData[2]=0x01;outputData[3]=0x1e;await device.sendReport(0, outputData); // 发送数据,第一个参数为reportId,填0表示不使用reportId} async function piccrequest() {if (!device?.opened) {alert("请先选择已连接的读卡器!");return;}textarea.value = ""; carduid.value="";card8h10dz.value="";card8h10df.value="";const outputData = new Uint8Array(32);outputData[0]=0x78; outputData[1]=0x68; outputData[2]=0x01;outputData[3]=0xf0;await device.sendReport(0, outputData); // 发送数据,第一个参数为reportId,填0表示不使用reportId}function request_loop() {if (!device?.opened) {alert("请先选择已连接的读卡器!");return;}if (document.getElementById('butt_readloop').value == '轮询读取M1卡UID') {document.getElementById('butt_readloop').value = '停止轮询';ButtonDisable();time1 = setInterval("piccrequest()", 500); //开启间隔500毫秒寻一次卡} else {document.getElementById('butt_readloop').value = '轮询读取M1卡UID';clearInterval(time1);ButtonEnabled();}}async function sfzrequest() {if (!device?.opened) {alert("请先选择已连接的读卡器!");return;}textarea.value = ""; sfzuid.value="";const outputData = new Uint8Array(32);outputData[0]=0x78; outputData[1]=0x68; outputData[2]=0x01;outputData[3]=0x50;await device.sendReport(0, outputData); // 发送数据,第一个参数为reportId,填0表示不使用reportId}async function iclassrequest() {if (!device?.opened) {alert("请先选择已连接的读卡器!");return;}textarea.value = ""; sfzuid.value="";const outputData = new Uint8Array(32);outputData[0]=0x78; outputData[1]=0x68; outputData[2]=0x01;outputData[3]=0x51;await device.sendReport(0, outputData); // 发送数据,第一个参数为reportId,填0表示不使用reportId}async function ntagrequest() {if (!device?.opened) {alert("请先选择已连接的读卡器!");return;}textarea.value = ""; ntaguid.value="";const outputData = new Uint8Array(32);outputData[0]=0x78; outputData[1]=0x68; outputData[2]=0x01;outputData[3]=0x10;await device.sendReport(0, outputData); // 发送数据,第一个参数为reportId,填0表示不使用reportId}async function iso15693request(){if (!device?.opened) {alert("请先选择已连接的读卡器!");return;}textarea.value = ""; uid15693.value="";const outputData = new Uint8Array(32);outputData[0]=0x78; outputData[1]=0x68; outputData[2]=0x0d;outputData[3]=0x21;outputData[4]=0x16;outputData[15]=0xdd;await device.sendReport(0, outputData); // 发送数据,第一个参数为reportId,填0表示不使用reportId}function ButtonEnabled() { //恢复各button 的onclick事件 document.getElementById("butt_beep").setAttribute("onclick", "beep()");document.getElementById("butt_getdevnum").setAttribute("onclick", "getdevicenumber()");document.getElementById("butt_piccrequest").setAttribute("onclick", "piccrequest()");//document.getElementById("butt_readloop").setAttribute("onclick", "request_loop()"); }window.onerror = function (e) {ButtonEnabled(); //恢复按键的onclick事件clearInterval(time1);document.getElementById('butt_readloop').value = '轮询读取IC卡卡号';alert("不好意思,出错了!");return true;//屏蔽系统事件}</script><style>th {background-color:#F6FAFF; color: blue;font-family:楷体;}td {background-color:#F6FAFF; font-family:楷体;}
</style>
</head>
<body>
<table width="866" height="346" align="center"><tr><th width="124" height="45" scope="row"><input style="width:120px" name="butt_selectdev" type="submit" id="butt_selectdev" onclick="selectdev()" value="选择连接的读卡器" /></th><td width="716">
</td>
</tr>
设备编号:原始16进制卡号:,转8H10D正码:,8H10D反码:
<tr><th width="124" height="45" scope="row"><input style="width:120px" name="butt_sfzrequest" type="submit" id="butt_sfzrequest" onclick="sfzrequest()" value="读取二代证UID" /></th><td >原始16进制卡号:<input style="color:red;text-align:center;" name="sfzuid" type="text" id="sfzuid" size="16" maxlength="16" /></td>
</tr><tr><th width="124" height="45" scope="row"><input style="width:120px" name="butt_iclassrequest" type="submit" id="butt_iclassrequest" onclick="iclassrequest()" value="读取iCLASS卡UID" /></th><td>原始16进制卡号:<input style="color:red;text-align:center;" name="iclassuid" type="text" id="iclassuid" size="16" maxlength="16" /></td>
</tr><tr><th width="124" height="45" scope="row"><input style="width:120px" name="butt_ntagrequest" type="submit" id="butt_ntagrequest" onclick="ntagrequest()" value="读取Ntag卡UID" /></th><td>原始16进制卡号:<input style="color:red;text-align:center;" name="ntaguid" type="text" id="ntaguid" size="16" maxlength="16" /></td>
</tr><tr><th width="124" height="45" scope="row"><input style="width:120px" name="butt_15693request" type="submit" id="butt_15693request" onclick="iso15693request()" value="读取15693卡UID" /></th><td>原始16进制卡号:<input style="color:red;text-align:center;" name="uid15693" type="text" id="uid15693" size="16" maxlength="16" /></td>
</tr>
操作提示
以上功能使用Web HID API技术,请使用支持Web HID API的浏览器!
`