Web网页写网址到424DNA标签Javascrip源码

本示例使用的发卡器:https://item.taobao.com/item.htm?spm=a21dvs.23580594.0.0.47b32c1bXBkiRl&ft=t&id=615391857885

javascript 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Ntag 424 DNA标签读写</title>

    <script language="javascript">
        var iswsrun = false;
        var ws;
        var received_msg = "";

        var mytimer;
        var strls = "";
        var errorno = "";
        var ApduCommandStr = "";

        var wsUri = "ws://127.0.0.1:39189";   //端口号必须与RFIDWebPlugin端口一致

        function isHex(val) {
            var testval = /^(\d|[A-F]|[a-f])+$/; // 十六进制数判断
            return (testval.test(val));
        }

        function intToHex(num, len) {
            return num.toString(16).padStart(len, '0');
        }

        function buttonDisable() {  // 删除button 的 onclick 事件,防止重复执行指令	
            document.getElementById("butt_beep").setAttribute("onclick", null);
            document.getElementById("butt_getdevnum").setAttribute("onclick", null);
            document.getElementById("butt_getcardtype").setAttribute("onclick", null);
            document.getElementById("butt_cpurequest1").setAttribute("onclick", null);
            document.getElementById("butt_selectappid").setAttribute("onclick", null);
            document.getElementById("butt_desfireauthkeyev2").setAttribute("onclick", null);
            document.getElementById("butt_ntagchangkey").setAttribute("onclick", null); 
            document.getElementById("butt_ntagsetconfiguration").setAttribute("onclick", null); 
            document.getElementById("butt_forumtype4_write_ndeftag_uri").setAttribute("onclick", null); 
            document.getElementById("butt_forumtype4getuid").setAttribute("onclick", null);
            document.getElementById("butt_forumtype4_read_ndeftag").setAttribute("onclick", null); 
            document.getElementById("butt_getcountervalue").setAttribute("onclick", null); 
            document.getElementById("butt_ntagreadfilesettings").setAttribute("onclick", null);
            document.getElementById("butt_ntagchangefilesettings").setAttribute("onclick", null);
        }

        function beepDevice() {	//驱动发卡器响声
            returninfo.value = "";
            buttonDisable();                 //删除按键的 onclick 事件,防止重复执行指令 
            WebSocketRun("pcdbeep,30");
        }

        function getdevicenumber() {         //读取发卡器唯一出厂序号,可以当加密狗使用			            
            returninfo.value = "";
            buttonDisable();                 //删除按键的 onclick 事件,防止重复执行指令 
            WebSocketRun("pcdgetdevicenumber");
        }

        function geticcardtype() {           //获取IC卡型号
            returninfo.value = "";
            buttonDisable();                 //删除按键的 onclick 事件,防止重复执行指令 
            WebSocketRun("getmifareversion");
        }

        function cpu_cpurequest1() {		//激活发卡器感应区内的CPU卡,获取CPU卡卡号	            
            returninfo.value = "";
            carduid.value = "";
            buttonDisable();                 //删除按键的 onclick 事件,防止重复执行指令 
            WebSocketRun("cpurequest1,");
        }

        function changeapp() {
            switch (seleappid.selectedIndex) {
                case 0:
                    selefileid.selectedIndex = 0;
                    selefci.selectedIndex = 0;
                    objedata.value = "D2 76 00 00 85 01 00";
                    break;
                case 1:
                    selefileid.selectedIndex = 1;
                    selefci.selectedIndex = 0;
                    objedata.value = "3F 00";
                    break;
                case 2:
                    selefileid.selectedIndex = 0;
                    selefci.selectedIndex = 0;
                    objedata.value = "D2 76 00 00 85 01 01";
                    break;
                case 3:
                    selefileid.selectedIndex = 1;
                    selefci.selectedIndex = 0;
                    objedata.value = "E1 10";
                    break;
                case 4:
                    selefileid.selectedIndex = 0;
                    selefci.selectedIndex = 1;
                    objedata.value = "A0 00 00 03 96 56 43 41 03 F0 15 40 00 00 00 0B";
                    break;
                case 5:
                    selefileid.selectedIndex = 1;
                    selefci.selectedIndex = 0;
                    objedata.value = "DF 01";
                    break;
            }
        }

        function selectappid() {      //发送选择卡内应用的apdu指令
            returninfo.value = "";

            ApduCommandStr = "00A4";
            if (selefileid.selectedIndex == 0) {
                ApduCommandStr = ApduCommandStr + "04";
            } else {
                ApduCommandStr = ApduCommandStr + "00";
            }
            if (selefci.selectedIndex == 0) {
                ApduCommandStr = ApduCommandStr + "00";
            } else {
                ApduCommandStr = ApduCommandStr + "0C";
            }
            objedatastr = objedata.value.replace(/\s/g, "");  //16进制的目标数据            
            if (!isHex(objedatastr) || (objedatastr.length % 2) != 0) {
                textarea.value = "16进制目标数据输入错误,请输入正确的16进制目标数据!";
                objedata.focus();
                objedata.select();
                return;
            }
            objedatalen = objedatastr.length / 2;    //Lc数据长度
            ApduCommandStr = ApduCommandStr + objedatalen.toString(16).padStart(2, '0') + objedatastr;                        

            buttonDisable();                 //删除按键的 onclick 事件,防止重复执行指令 
            WebSocketRun("cpuisoapdu," + ApduCommandStr);
        }

        function desfireauthkeyev2() {
            returninfo.value = "";
            keyid = selectauthkey.selectedIndex;       //认证密钥编号
            keytype = selectdecnec.selectedIndex;      //加解密方式
            keylen = 32;                                //密钥长度            
            authkeystr = text_authkey.value.trim().replace(/\s+/g, '');  //16进制的认证密钥
            if (!isHex(authkeystr) || authkeystr.length != keylen) {
                alert("认证密钥输入错误,请输入正确的16进制认证密钥!");
                text_authkey.focus();
                text_authkey.select();
                return;
            }

            buttonDisable();                 //删除按键的 onclick 事件,防止重复执行指令 
            WebSocketRun("desfireauthkeyev2," + authkeystr + "," + keyid + "," + keytype);
        }

        function ntagchangkey() {
            returninfo.value = "";
            keyid = selectnewkey.selectedIndex;         //需要更改的密钥编号
            keylen = 32;                                //密钥长度
            newkeystr = text_newkey.value.trim().replace(/\s+/g, '');  //16进制的新密钥
            if (!isHex(newkeystr) || newkeystr.length != keylen) {
                alert("新密钥输入错误,请输入正确的16进制新密钥!");
                text_newkey.focus();
                text_newkey.select();
                return;
            }

            authkeystr = text_authkey.value.trim().replace(/\s+/g, '');  //16进制的认证密钥
            if (!isHex(authkeystr) || authkeystr.length != keylen) {
                alert("认证密钥输入错误,请输入正确的16进制认证密钥!");
                text_authkey.focus();
                text_authkey.select();
                return;
            }

            buttonDisable();                 //删除按键的 onclick 事件,防止重复执行指令 
            WebSocketRun("ntagchangkey," + newkeystr + "," + keyid + ",1," + authkeystr);
        }

        function ntagsetconfiguration() {
            returninfo.value = "";
            var answer = confirm("424卡更改为随机UID模式后,此卡将永久为随机模式,此操作不可逆!确定要继续将卡更改为随机UID模式吗?");
            if (answer) { }
            else {
                return;
            }            
            optionval = 0;                   //操作代码
            setbuff = "02";                  //16进制的设置参数,00为固定UID,02为动态UID,特别警告,改为02后卡将会锁死这个序设定值,再也不能改回固定UID
            bufflen = 1;                     //参数长度 

            buttonDisable();                 //删除按键的 onclick 事件,防止重复执行指令 
            WebSocketRun("ntagsetconfiguration," + optionval + "," + setbuff + "," + bufflen);
        }

        function examples1() {            
            text_title.value = "百度";
            select_prefix.selectedIndex = 1;
            text_uri.value = "baidu.com?uid=00000000000000000000000000000000";

            select_SetCommMode.selectedIndex = 0;       //通讯模式为明文
            select_readonlykey.selectedIndex = 5;       //只读指令需要先认证的密钥
            select_writeonlykey.selectedIndex = 5;      //只写指令需要先认证的密钥
            select_readwritekey.selectedIndex = 5;      //读写指令需要先认证的密钥
            select_changesetkey.selectedIndex = 0;      //更改设置指令需要先认证的密钥
            select_SDMRead.selectedIndex = 0;           //SDM元数据读取访问权限
            select_CMACCalc.selectedIndex = 5;          //CMAC计算的派生密钥
            select_SDMCount.selectedIndex = 6;          //SDM计数器检索密钥

            check_SDMMirrorImageEn.checked = true;      //启用SDM镜像
            check_UIDMirrorImageEn.checked = true;      //启用UID镜像
            check_CounMirrorImageEn.checked = false;    //启用计数器镜像
            check_CounLimitEn.checked = false;          //启用计数器限额
            check_SDMENCFileData.checked = false;       //check_SDMENCFileData
            
            text_UIDMirrorImage.value = 0;              //UID镜像位置
            text_PICCDataOffset.value = 26;             //PICCDataOffset
            text_SDMMACInputOffset.value = 0;
            text_SDMMACoffset.value = 0;
            text__Counoffset.value = 0;                 //计数器数据位置
            text_CounLimit.value = 0;                   //计数器限额值
            text_SDMENCOffset.value = 0;
            text_SDMENCLength.value = 0;
        }

        function examples2() {
            text_title.value = "百度";
            select_prefix.selectedIndex = 1;
            text_uri.value = "baidu.com?uid=00000000000000x000000";

            select_SetCommMode.selectedIndex = 0;       //通讯模式为明文
            select_readonlykey.selectedIndex = 5;       //只读指令需要先认证的密钥
            select_writeonlykey.selectedIndex = 5;      //只写指令需要先认证的密钥
            select_readwritekey.selectedIndex = 5;      //读写指令需要先认证的密钥
            select_changesetkey.selectedIndex = 0;      //更改设置指令需要先认证的密钥
            select_SDMRead.selectedIndex = 5;           //SDM元数据读取访问权限
            select_CMACCalc.selectedIndex = 5;          //CMAC计算的派生密钥
            select_SDMCount.selectedIndex = 5;          //SDM计数器检索密钥

            check_SDMMirrorImageEn.checked = true;      //启用SDM镜像
            check_UIDMirrorImageEn.checked = true;      //启用UID镜像
            check_CounMirrorImageEn.checked = true;    //启用计数器镜像
            check_CounLimitEn.checked = false;          //启用计数器限额
            check_SDMENCFileData.checked = false;       //check_SDMENCFileData

            text_UIDMirrorImage.value = 26;              //UID镜像位置
            text_PICCDataOffset.value = 0;             //PICCDataOffset
            text_SDMMACInputOffset.value = 0;
            text_SDMMACoffset.value = 0;
            text__Counoffset.value = 41;                 //计数器数据位置
            text_CounLimit.value = 0;                   //计数器限额值
            text_SDMENCOffset.value = 0;
            text_SDMENCLength.value = 0;
        }

        function examples3() {
            text_title.value = "";
            select_prefix.selectedIndex = 1;
            text_uri.value = "baidu.com?picc_data=00000000000000000000000000000000&e=12345678901234560000000000000000&cmac=0000000000000000";

            select_SetCommMode.selectedIndex = 0;       //通讯模式为明文
            select_readonlykey.selectedIndex = 5;       //只读指令需要先认证的密钥
            select_writeonlykey.selectedIndex = 5;      //只写指令需要先认证的密钥
            select_readwritekey.selectedIndex = 5;      //读写指令需要先认证的密钥
            select_changesetkey.selectedIndex = 0;      //更改设置指令需要先认证的密钥
            select_SDMRead.selectedIndex = 0;           //SDM元数据读取访问权限
            select_CMACCalc.selectedIndex = 0;          //CMAC计算的派生密钥
            select_SDMCount.selectedIndex = 0;          //SDM计数器检索密钥

            check_SDMMirrorImageEn.checked = true;      //启用SDM镜像
            check_UIDMirrorImageEn.checked = true;      //启用UID镜像
            check_CounMirrorImageEn.checked = true;     //启用计数器镜像
            check_CounLimitEn.checked = false;          //启用计数器限额
            check_SDMENCFileData.checked = true;        //check_SDMENCFileData

            text_UIDMirrorImage.value = 0;              //UID镜像位置
            text_PICCDataOffset.value = 27;             //PICCDataOffset
            text_SDMMACInputOffset.value = 62;
            text_SDMMACoffset.value = 100;
            text__Counoffset.value = 0;                 //计数器数据位置
            text_CounLimit.value = 0;                   //计数器限额值
            text_SDMENCOffset.value = 62;
            text_SDMENCLength.value =32;

        }

        function getCaretPos() {
            Cursoroffset = 7 + text_uri.selectionStart;
            if (text_title.value.length > 0) {
                Cursoroffset = Cursoroffset + 5;
            }
            text_selestar.value = Cursoroffset;
        }

        function forumtype4_write_ndeftag_uri() {
            returninfo.value = "";
            titlestr = text_title.value.trim();					//标题
            uriheader = String(select_prefix.selectedIndex);	//前缀
            uriinfo = text_uri.value;					        //uri链接  

            myctrlword = 0;                 //写卡不需要认证卡片密钥  
            picckey = "";

            if (check_RWAuthKey.checked) {  //AES-128密文+MAC模式 认证写卡               
                myctrlword = 64;        

                if (select_RWCommMode.selectedIndex == 2) {
                    myctrlword = myctrlword + 3;         //bit1-0为3表示通信模式为密文+MAC模式
                }else{
                    if (select_RWCommMode.selectedIndex == 1) {
                        myctrlword = myctrlword + 1;     //bit1-0为1表示通信模式为MAC,
                    }
                }             
                picckey = "04";     //AES,用71指令认证                
                picckey = picckey + select_RWAuthKeyId.selectedIndex.toString(16).padStart(2, '0');    //认证密钥编号
                authkeystr = text_RWauthkey.value.trim().replace(/\s+/g, '');  //16进制的认证密钥
                if (!isHex(authkeystr) || authkeystr.length != 32) {
                    alert("认证密钥输入错误,请输入正确的16进制认证密钥!");
                    text_RWauthkey.focus();
                    text_RWauthkey.select();
                    return;
                }
                picckey = picckey + authkeystr;
            }

            buttonDisable();                 //删除按键的 onclick 事件,防止重复执行指令 
            WebSocketRun("forumtype4_write_ndeftag," + titlestr + "," + uriheader + "," + uriinfo + "," + myctrlword + "," + picckey);
        }

        function forumtype4getuid() {
            returninfo.value = "";
            picckey = "04";     //AES,用71指令认证                
            picckey = picckey + select_RWAuthKeyId.selectedIndex.toString(16).padStart(2, '0');    //认证密钥编号
            authkeystr = text_RWauthkey.value.trim().replace(/\s+/g, '');  //16进制的认证密钥
            if (!isHex(authkeystr) || authkeystr.length != 32) {
                alert("认证密钥输入错误,请输入正确的16进制认证密钥!");
                text_RWauthkey.focus();
                text_RWauthkey.select();
                return;
            }
            picckey = picckey + authkeystr;
            buttonDisable();                 //删除按键的 onclick 事件,防止重复执行指令 
            WebSocketRun("forumtype4getuid," + picckey);
        }

        function forumtype4_read_ndeftag() {
            returninfo.value = "";

            if (check_RWAuthKey.checked) {   //AES-128密文+MAC模式 认证读卡                 
                if (select_RWCommMode.selectedIndex == 2) {
                    myctrlword = myctrlword + 3;         //bit1-0为3表示通信模式为密文+MAC模式
                } else {
                    if (select_RWCommMode.selectedIndex == 1) {
                        myctrlword = myctrlword + 1;     //bit1-0为1表示通信模式为MAC,
                    }
                }
                picckey = "04";     //AES,用71指令认证                
                picckey = picckey + select_RWAuthKeyId.selectedIndex.toString(16).padStart(2, '0');    //认证密钥编号
                authkeystr = text_RWauthkey.value.trim().replace(/\s+/g, '');  //16进制的认证密钥
                if (!isHex(authkeystr) || authkeystr.length != 32) {
                    alert("认证密钥输入错误,请输入正确的16进制认证密钥!");
                    text_RWauthkey.focus();
                    text_RWauthkey.select();
                    return;
                }
                myctrlword = 64;
                picckey = picckey + authkeystr;
                keylen = 18;
            } else {
                myctrlword = 0;                                       //读卡不需要认证卡片密钥   
                picckey = "000000000000000000000000000000000000";     //18字节占位符
                keylen = 0;                                           //密钥长度
            }

            if (check_AnalyzeImage.checked) {  //解析镜像                
                sdmkeystr = text_SDMkey.value.trim().replace(/\s+/g, '');  //16进制的SDM解析密钥
                if (!isHex(sdmkeystr) || sdmkeystr.length != 32) {
                    alert("SDM解析密钥输入错误,请输入正确的16进制SDM解析密钥!");
                    text_SDMkey.focus();
                    text_SDMkey.select();
                    return;
                }
                picckey = picckey + sdmkeystr;

                cmackeystr = text_CMACkey.value.trim().replace(/\s+/g, '');  //16进制的CMAC验证密钥
                if (!isHex(cmackeystr) || cmackeystr.length != 32) {
                    alert("CMAC验证密钥输入错误,请输入正确的16进制CMAC验证密钥!");
                    text_CMACkey.focus();
                    text_CMACkey.select();
                    return;
                }
                myctrlword = myctrlword + 4;
                picckey = picckey + cmackeystr;
                keylen = 50;
            }
            
            buttonDisable();                 //删除按键的 onclick 事件,防止重复执行指令 
            WebSocketRun("forumtype4_read_ndeftag," + myctrlword + "," + keylen + "," + picckey);
        }

        function getcountervalue() {
            returninfo.value = "";
            ApduCommandStr = "90F60000010200";            
            buttonDisable();                 //删除按键的 onclick 事件,防止重复执行指令 
            WebSocketRun("cpuisoapdu," + ApduCommandStr);
        }

        function ntagreadfilesettings() {
            returninfo.value = "";
            text_setup.value = "";
            buttonDisable();                 //删除按键的 onclick 事件,防止重复执行指令 
            WebSocketRun("ntagreadfilesettings," + select_RWsetconnmodel.selectedIndex + ",2");  //2号文件为NDEF文件默认通信模式为明文,3号普通数据文件为默认通信模式为密文+MAC保护,1号文件 是CC文件)
        }

        function ntagchangefilesettings() {
            returninfo.value = "";

            const settingsbuf = new Uint8Array(32);
            if (select_SetCommMode.selectedIndex == 1) {  
                settingsbuf[0] = 0x01;             //MAC保护
            } else {
                if (select_SetCommMode.selectedIndex == 2) {
                    settingsbuf[0] = 0x03;         //密文+MAC保护
                } else { settingsbuf[0] = 0x00; }  //明文
            }

            if (check_SDMMirrorImageEn.checked) {  
                settingsbuf[0] = settingsbuf[0]+0x40;  //启用SDM镜像
            }

            if (select_changesetkey.selectedIndex < 5) {  //更改指令 需要先认证的密码
                settingsbuf[1] = select_changesetkey.selectedIndex;
            } else {
                if (select_changesetkey.selectedIndex == 5) {
                    settingsbuf[1] = 0x0e;                //无需密码,直接用明文
                } else { settingsbuf[1] = 0x0f; }         //禁止该指令
            }
                
            if (select_readwritekey.selectedIndex < 5) {  //读写指令 需要先认证的密码
                settingsbuf[1] = settingsbuf[1] + select_readwritekey.selectedIndex *16;
            } else {
                if (select_readwritekey.selectedIndex == 5) {
                    settingsbuf[1] = settingsbuf[1]+ 0xe0;                //无需密码,直接用明文
                } else { settingsbuf[1] = settingsbuf[1] + 0xf0; }        //禁止该指令
            }

            if (select_writeonlykey.selectedIndex < 5) {  //只写指令 需要先认证的密码
                settingsbuf[2] = select_writeonlykey.selectedIndex;
            } else {
                if (select_writeonlykey.selectedIndex == 5) {
                    settingsbuf[2] = 0x0e;                //无需密码,直接用明文
                } else { settingsbuf[2] = 0x0f; }         //禁止该指令
            }

            if (select_readonlykey.selectedIndex < 5) {  //只读指令 需要先认证的密码
                settingsbuf[2] = settingsbuf[2] + select_readonlykey.selectedIndex * 16;
            } else {
                if (select_readonlykey.selectedIndex == 5) {
                    settingsbuf[2] = settingsbuf[2] + 0xe0;               //无需密码,直接用明文
                } else { settingsbuf[2] = settingsbuf[2] + 0xf0; }        //禁止该指令
            }

            j = 3;

            if ((settingsbuf[0] & 0x40) > 0) {  //已经启用SDM镜像
                settingsbuf[3] = 0x01;
                if (check_UIDMirrorImageEn.checked) {
                    settingsbuf[3] = settingsbuf[3] + 0x80;               //启用UID镜像                    
                }

                if (check_CounMirrorImageEn.checked) {
                    settingsbuf[3] = settingsbuf[3] + 0x40;               //启用计数器镜像                    
                }
                if (check_CounLimitEn.checked) {
                    settingsbuf[3] = settingsbuf[3] + 0x20;               //启用计数器限额                
                }
                if (check_SDMENCFileData.checked) {
                    settingsbuf[3] = settingsbuf[3] + 0x10;               //启用SDMENCFileData                
                }

                settingsbuf[4] = 0xf0;

                if (select_SDMCount.selectedIndex < 5) {  //计数器访问 需要先认证的密码
                    settingsbuf[4] = settingsbuf[4] + select_SDMCount.selectedIndex ;
                } else {
                    if (select_SDMCount.selectedIndex == 5) {
                        settingsbuf[4] = settingsbuf[4] + 0x0e;               //无需密码,直接用明文
                    } else { settingsbuf[4] = settingsbuf[4] + 0x0f; }        //禁止该指令
                }
                
                if (select_SDMRead.selectedIndex < 5) {  //SDMMetaRead 需要先认证的密码
                    settingsbuf[5] =  select_SDMRead.selectedIndex * 16;
                } else {
                    if (select_SDMRead.selectedIndex == 5) {
                        settingsbuf[5] =  0xe0;               //无需密码,直接用明文
                    } else { settingsbuf[5] =  0xf0; }        //禁止该指令
                }

                j = j + 1;

                if (select_CMACCalc.selectedIndex < 5) {      //CMAC计算派生 需要先认证的密码
                    settingsbuf[5] = settingsbuf[5] + select_CMACCalc.selectedIndex;
                } else {                   
                    settingsbuf[5] = settingsbuf[5] + 0x0f;   //禁止该指令
                }

                j = 6;

                if ((settingsbuf[5] & 0xf0) == 0xe0) {
                    if ((settingsbuf[3] & 0x80) > 0) {     //UID镜像位置
                        longi = text_UIDMirrorImage.value;      
                        settingsbuf[6] = longi;
                        settingsbuf[7] = longi / 256;
                        settingsbuf[8] = longi / 65536;
                        j = 9;
                    }
                    if ((settingsbuf[3] & 0x40) > 0) {     //计数器镜像
                        longi = text__Counoffset.value;
                        settingsbuf[j] = longi;
                        settingsbuf[j+1] = longi / 256;
                        settingsbuf[j+2] = longi / 65536;
                        j = j+3;
                    }
                } else {
                    if ((settingsbuf[5] & 0xf0) < 0x50) {  
                        longi = text_PICCDataOffset.value;  //ENCPICCDataOffset(UID和随机数加密后的数据位置)
                        settingsbuf[6] = longi;
                        settingsbuf[7] = longi / 256;
                        settingsbuf[8] = longi / 65536;
                        j = 9;
                    }
                }

                if ((settingsbuf[5] & 0x0f) != 0x0f) {
                    longi = text_SDMMACInputOffset.value;       //SDMMACInputOffset
                    settingsbuf[j] = longi;
                    settingsbuf[j + 1] = longi / 256;
                    settingsbuf[j + 2] = longi / 65536;
                    j = j + 3;

                    if ((settingsbuf[3] & 0x10) > 0x00) {
                        longi = text_SDMENCOffset.value;       //SDMENCOffset
                        settingsbuf[j] = longi;
                        settingsbuf[j + 1] = longi / 256;
                        settingsbuf[j + 2] = longi / 65536;
                        j = j + 3;

                        longi = text_SDMENCLength.value;       //SDMENCLength
                        settingsbuf[j] = longi;
                        settingsbuf[j + 1] = longi / 256;
                        settingsbuf[j + 2] = longi / 65536;
                        j = j + 3;
                    }

                    longi = text_SDMMACoffset.value;       //SDMMACOffset
                    settingsbuf[j] = longi;
                    settingsbuf[j + 1] = longi / 256;
                    settingsbuf[j + 2] = longi / 65536;
                    j = j + 3;
                }

                if ((settingsbuf[3] & 0x20) > 0x00) {     
                    longi = text_CounLimit.value;       //计数器限额值
                    settingsbuf[j] = longi;
                    settingsbuf[j + 1] = longi / 256;
                    settingsbuf[j + 2] = longi / 65536;
                    j = j + 3;
                }
            }

            //参数设定规则校验------------------------------------------------------
            if ((settingsbuf[0] & 0x40) > 0x00) {    //已经启用SDM镜像
                if ((settingsbuf[3] & 0xc0) == 0x00) {
                    alert("当开启SDM镜像时,必须开启UID镜像或计数器镜像!");
                    return;
                }

                if ((settingsbuf[3] & 0x80) > 0x00) { //已经启用UID镜像
                    if ((settingsbuf[5] & 0xf0) == 0xf0) {
                        alert("当启用UID镜像时,SDM元数据读取访问权限不能为禁止!");
                        return;
                    }
                } else {
                    if ((settingsbuf[5] & 0xf0) < 0xf0) {
                        alert("当不开启UID镜像时,SDM元数据读取访问权限只能为禁止!");
                        return;
                    }
                }

                if ((settingsbuf[3] & 0x40) == 0x00) {  //当不开启计数器镜像时
                    if ((settingsbuf[4] & 0x0f) < 0x0f) {
                        alert("当不开启计数器镜像时,SDM计数器检索密钥只能为禁止!");
                        return;
                    }
                }

                if (((settingsbuf[3] & 0x80) > 0x00) | ((settingsbuf[5] & 0xf0) < 0x50)) {
                    i = 9;        //存在UIDOffset或PICCDataOffset
                } else { i = 6;}

                if (settingsbuf[5] == 0xe0) {
                    i = i + 3;      //SDMReadCtrOffset存在
                }

                if ((settingsbuf[5] & 0x0f) < 0x05) {  //SDMFileRead access right
                    SDMMACInputOffset = settingsbuf[i] + settingsbuf[i + 1] * 256 + settingsbuf[i + 2] * 65536;
                    i = i + 3;

                    if ((settingsbuf[3] & 0x10) > 0x00) {  //SDMENCFileData
                        SDMENCOffset = settingsbuf[i] + settingsbuf[i + 1] * 256 + settingsbuf[i + 2] * 65536;
                        i = i + 3;

                        SDMENCLength = settingsbuf[i] + settingsbuf[i + 1] * 256 + settingsbuf[i + 2] * 65536;
                        i = i + 3;
                    }

                    SDMMACOffset = settingsbuf[i] + settingsbuf[i + 1] * 256 + settingsbuf[i + 2] * 65536;
                    i = i + 3;

                    if ((settingsbuf[3] & 0x10) > 0x00) {  //SDMENCFileData
                        if (SDMENCOffset < SDMMACInputOffset) {
                            alert("SDMENCOffset不能小于SDMMACInputOffset!");
                            return;
                        }
                        if (SDMENCLength < 32) {
                            alert("SDMENCLength不能小于32!");
                            return;
                        }
                        if (SDMMACOffset < (SDMENCOffset + SDMENCLength)) {
                            alert("SDMMACOffset不能小于(SDMENCOffset + SDMENCLength)!");
                            return;
                        }
                    } else {
                        if(SDMMACOffset < SDMMACInputOffset){
                            alert("SDMMACOffset不能小于SDMMACInputOffset!");
                            return;
                        }
                    }
                }
            }
            //------------------------------------------------------------------------------------------------------------
            setdatahex = "";
            for (i = 0; i < j; i++) {
                setdatahex = setdatahex + settingsbuf[i].toString(16).padStart(2, '0').toUpperCase();
            }
            text_setup.value = setdatahex;

            buttonDisable();                 //删除按键的 onclick 事件,防止重复执行指令 
            WebSocketRun("ntagchangefilesettings," + select_RWsetconnmodel.selectedIndex + ",2," + setdatahex + "," + j);  //2号文件为NDEF文件默认通信模式为明文,3号普通数据文件为默认通信模式为密文+MAC保护,1号文件 是CC文件)
        }

        function ButtonEnabled() {  //恢复各button 的onclick事件
            document.getElementById("butt_beep").setAttribute("onclick", "beepDevice()");
            document.getElementById("butt_getdevnum").setAttribute("onclick", "getdevicenumber()");
            document.getElementById("butt_getcardtype").setAttribute("onclick", "geticcardtype()");
            document.getElementById("butt_cpurequest1").setAttribute("onclick", "cpu_cpurequest1()");
            document.getElementById("butt_selectappid").setAttribute("onclick", "selectappid()");
            document.getElementById("butt_desfireauthkeyev2").setAttribute("onclick", "desfireauthkeyev2()"); 
            document.getElementById("butt_ntagchangkey").setAttribute("onclick", "ntagchangkey()");
            document.getElementById("butt_ntagsetconfiguration").setAttribute("onclick", "ntagsetconfiguration()");
            document.getElementById("butt_forumtype4_write_ndeftag_uri").setAttribute("onclick", "forumtype4_write_ndeftag_uri()");
            document.getElementById("butt_forumtype4getuid").setAttribute("onclick", "forumtype4getuid()"); 
            document.getElementById("butt_forumtype4_read_ndeftag").setAttribute("onclick", "forumtype4_read_ndeftag()");
            document.getElementById("butt_getcountervalue").setAttribute("onclick", "getcountervalue()");
            document.getElementById("butt_ntagreadfilesettings").setAttribute("onclick", "ntagreadfilesettings()"); 
            document.getElementById("butt_ntagchangefilesettings").setAttribute("onclick", "ntagchangefilesettings()");
        }

        function DispErrInfo(Errcode) {
            var errstr = "";
            switch (Errcode) {
                case "ReturnCode:001":
                    errstr = ",读写扇区数据失败!";
                    break;
                case "ReturnCode:002":
                    errstr = ",读写1、2块数据失败!";
                    break;
                case "ReturnCode:003":
                    errstr = ",请先激活CPU卡再继续操作!";
                    break;
                case "ReturnCode:008":
                    errstr = ",未寻到卡,请将卡放到发卡器的感应区!";
                    break;
                case "ReturnCode:009":
                    errstr = ",有多张卡在感应区,寻卡过程中防冲突失败,读卡失败!";
                    break;
                case "ReturnCode:010":
                    errstr = ",该卡可能已被休眠,无法选中卡片!";
                    break;
                case "ReturnCode:011":
                    errstr = ",密码装载失败!";
                    break;
                case "ReturnCode:012":
                    errstr = ",卡密码认证失败!";
                    break;
                case "ReturnCode:013":
                    errstr = ",读块操作失败,原因是刷卡太快或本块所对应的区还没通过密码认证!";
                    break;
                case "ReturnCode:014":
                    errstr = ",写块操作失败,原因是刷卡太快或本块所对应的区还没通过密码认证!";
                    break;
                case "ReturnCode:018":
                    errstr = ",写块操作失败!";
                    break;
                case "ReturnCode:021":
                    errstr = ",没有动态库!";
                    break;
                case "ReturnCode:022":
                    errstr = ",动态库或驱动程序异常!";
                    break;
                case "ReturnCode:023":
                    errstr = ",驱动程序错误或发卡器未连接!";
                    break;
                case "ReturnCode:024":
                    errstr = ",操作超时,一般是动态库没有反映!";
                    break;
                case "ReturnCode:025":
                    errstr = ",发送字数不够!";
                    break;
                case "ReturnCode:026":
                    errstr = ",发送的CRC错!";
                    break;
                case "ReturnCode:027":
                    errstr = ",接收的字数不够!";
                    break;
                case "ReturnCode:028":
                    errstr = ",接收的CRC错!";
                    break;
                case "ReturnCode:029":
                    errstr = ",函数输入参数格式错误!";
                    break;
                case "ReturnCode:041":
                    errstr = ",写文件失败,请检查通信模式是否正确!";
                    break;
                case "ReturnCode:045":
                    errstr = ",此卡不支持更改UID号或UID块已被锁定!";
                    break;
                case "ReturnCode:046":
                    errstr = ",信息过大,标签容量不足!";
                    break;
                case "ReturnCode:047":
                    errstr = ",读文件失败,请检查通信模式是否正确!";
                    break;
                case "ReturnCode:050":
                    errstr = ",RATS错误,厂家调试代码,用户不需理会!";
                    break;
                case "ReturnCode:051":
                    errstr = ",PPS错误,厂家调试代码,用户不需理会!";
                    break;
                case "ReturnCode:052":
                    errstr = ",已进入了14443-4协议状态,可进行CPU卡功能所有操作!";
                    break;
                case "ReturnCode:053":
                    errstr = ",未寻到卡,请将卡放到发卡器的感应区!";
                    break;
                case "ReturnCode:054":
                    errstr = ",CPU卡功能通讯错误!";
                    break;
                case "ReturnCode:055":
                    errstr = ",发送ACK指令给卡,让卡接着发送数据回来!";
                    break;
                case "ReturnCode:056":
                    errstr = ",清空根目录失败!";
                    break;
                case "ReturnCode:057":
                    errstr = ",卡片不支持Forum_Type4协议,请先认证打勾选中"需要认证密码再写入"再试,如果还有此提示,可能该卡不是Forum_Type4_Tag卡!";
                    break;
                case "ReturnCode:058":
                    errstr = ",卡片初始化失败!";
                    break;
                case "ReturnCode:059":
                    errstr = ",分配的空间不足!";
                    break;
                case "ReturnCode:060":
                    errstr = ",本次操作的实体已存在!";
                    break;
                case "ReturnCode:061":
                    errstr = ",无足够空间!";
                    break;
                case "ReturnCode:062":
                    errstr = ",文件不存在!";
                    break;
                case "ReturnCode:063":
                    errstr = ",权限不足,有可能是用只读密码认证,导致无法更改读写密码或无法写文件!";
                    break;
                case "ReturnCode:064":
                    errstr = ",密码不存在,或密钥文件未创建!";
                    break;
                case "ReturnCode:065":
                    errstr = ",传送长度错误!";
                    break;
                case "ReturnCode:066":
                    errstr = ",接收长度错误,即接收的数据长度指定过大!";
                    break;
                case "ReturnCode:067":
                    errstr = ",功能不支持、或卡中无MF、或卡片已锁定!";
                    break;
                case "ReturnCode:068":
                    errstr = ",密码认证错识次数过多,该密码已被锁死!";
                    break;
                case "ReturnCode:070":
                case "ReturnCode:071":
                case "ReturnCode:072":
                case "ReturnCode:073":
                case "ReturnCode:074":
                case "ReturnCode:075":
                case "ReturnCode:076":
                case "ReturnCode:077":
                case "ReturnCode:078":
                case "ReturnCode:079":
                case "ReturnCode:080":
                case "ReturnCode:081":
                case "ReturnCode:082":
                case "ReturnCode:083":
                case "ReturnCode:084":
                case "ReturnCode:085":
                    var lastnum = Errcode.substring(Errcode.lenth - 2, 2) - 70;
                    errstr = ",密码错误,剩余次数为:" + lastnum + ",如剩余次数为0,该密码将锁死,无法再认证!";
                    break;
                case "ReturnCode:086":
                    errstr = ",更改后的密码长度必须和创建时的长度一致!";
                    break;
                case "ReturnCode:087":
                    errstr = ",应用目录不存在!";
                    break;
                case "ReturnCode:088":
                    errstr = ",应用文件不存在!";
                    break;
                case "ReturnCode:089":
                    errstr = ",文件号不能超过 5 !";
                    break;
                case "ReturnCode:090":
                    errstr = ",读取文件时返回的长度不足,数据可能不正确!";
                    break;
                case "ReturnCode:091":
                    errstr = ",一次读文件的长度不能超过255 !";
                    break;
                case "ReturnCode:092":
                    errstr = ",一次写文件的长度不能超过247 !";
                    break;
                case "ReturnCode:444":
                    errstr = ",RFIDWebPlugin系统文件错误!";
                    break;
                case "ReturnCode:555":
                    errstr = ",未发现有效的NFC标签!";
                    break;
                default:
                    errstr = ",未知的错误!";
            }
            return errstr;
        }

        function ReturnCodeDes(ReturnCode) {
            var infostr = "";
            ReturnCode = ReturnCode.replace(/\s+/g, '');
            if (ReturnCode.slice(0, 3) == "63C") {

            } else {
                switch (ReturnCode) {
                    case "9000":
                        infostr = "成功!";
                        break;
                    case "9100":
                        infostr = "成功!";
                        break;
                    case "6281":
                        infostr = "回送的数据可能错误!";
                        break;
                    case "6283":
                        infostr = "选择文件无效,文件或密钥校验错误!";
                        break;
                    case "6400":
                        infostr = "状态标志未改变!";
                        break;
                    case "6581":
                        infostr = "写EEPROM 不成功!";
                        break;
                    case "6700":
                        infostr = "长度错误!";
                        break;
                    case "6900":
                        infostr = "CLA 与线路保护要求不匹配!";
                        break;
                    case "6901":
                        infostr = "无效的状态!";
                        break;
                    case "6981":
                        infostr = "命令与文件结构不相容!";
                        break;
                    case "6982":
                        infostr = "不满足安全状态!";
                        break;
                    case "6983":
                        infostr = "密钥被锁死!";
                        break;
                    case "6984":
                        infostr = "MAC格式不符合!";
                        break;
                    case "6985":
                        infostr = "使用条件不满足!";
                        break;
                    case "6986":
                        infostr = "请先选择文件!";
                        break;
                    case "6987":
                        infostr = "无安全报文!";
                        break;
                    case "6988":
                        infostr = "安全报文数据项不正确!";
                        break;
                    case "6A80":
                        infostr = "数据域参数错误!";
                        break;
                    case "6A81":
                        infostr = "功能不支持或卡中无MF 或卡片已锁定!";
                        break;
                    case "6A82":
                        infostr = "文件未找到!";
                        break;
                    case "6A83":
                        infostr = "记录未找到!";
                        break;
                    case "6A84":
                        infostr = "文件无足够空间!";
                        break;
                    case "6A86":
                        infostr = "参数P1 P2 错误!";
                        break;
                    case "6A88":
                        infostr = "密钥未找到!";
                        break;
                    case "6B00":
                        infostr = "状态标志未改变在达到Le/Lc 字节之前文件结束,偏移量错误!";
                        break;
                    case "6E00":
                        infostr = "无效的CLA!";
                        break;
                    case "6F00":
                        infostr = "数据无效!";
                        break;
                    case "9302":
                        infostr = "MAC 错误!";
                        break;
                    case "9303":
                        infostr = "应用已被锁定!";
                        break;
                    case "9401":
                        infostr = "金额不足!";
                        break;
                    case "9403":
                        infostr = "密钥未找到!";
                        break;
                    case "9406":
                        infostr = "所需的MAC 不可用!";
                        break;
                    case "91AE":
                        infostr = "认证失败,请检查命行的参数和前期计算是否错误!";
                        break;
                    case "91CA":
                        infostr = "上一个命令未完全完成!";
                        break;
                    case "917E":
                        infostr = "指令长度错误,如果上一条操作为密码认证,本次指令必需用密文+MAC保护的通信模式,否则用明文的通信模式";
                        break;
                    case "9140":
                        infostr = "当前目录或应用密钥不存在,请先选择正确的目录或应用!";
                        break;
                    case "919D":
                        infostr = "处于未验证密码的状态,该指令无法操作!";
                        break;
                    case "911E":
                        infostr = "MAC错误!";
                        break;
                    case "91F0":
                        infostr = "该文件号不存在!";
                        break;
                    case "919E":
                        infostr = "参数无效!";
                        break;
                    case "91BE":
                        infostr = "试图读取/写入的数据超出文件/记录的边界!";
                        break;
                    case "91A0":
                        infostr = "请求的 AID 不存在!";
                        break;
                    case "910C":
                        infostr = "备份文件不改变,不需要CommitTransaction和AbortTransaction!";
                        break;
                    default:
                        infostr = "未知的状态!";
                }
            }
            return infostr;
        }

        window.onerror = function (e) {   //异常提示
            ButtonEnabled();  //恢复按键的onclick事件
            alert("不好意思,出错了!");
            return true;     //屏蔽系统事件
        }

        function timeoutevent() {  //websockket通讯超时
            ws.close();
            returninfo.value = "websockket返回超时";
            ButtonEnabled();  //恢复按键的onclick事件
        }
        
        function WebSocketRev(evt) {   //websockket数据处理
            clearTimeout(mytimer);
            received_msg = evt.data;
            ws.close();

            //在这里解析返回数据			            		
            var strlist = received_msg.split(",");
            if (strlist.length > 1) {
                var dispstr = "";
                switch (strlist[0]) {
                    case "pcdbeep":
                        dispstr = "函数名称:" + strlist[0] + "\r\n";
                        if (strlist[1] == "ReturnCode:000") {
                            dispstr = dispstr + "操作结果:" + strlist[1] + ",已执行蜂鸣响声操作!\r\n"
                        } else {
                            dispstr = dispstr + "操作结果:" + strlist[1] + DispErrInfo(strlist[1]);
                        }
                        returninfo.value = dispstr;
                        break;

                    case "pcdgetdevicenumber":
                        dispstr = "函数名称:" + strlist[0] + "\r\n";
                        if (strlist[1] == "ReturnCode:000") {
                            dispstr = dispstr + "操作结果:" + strlist[1];
                            dispstr = dispstr + ",已读取设备编号!\r\n";
                        } else {
                            dispstr = dispstr + "操作结果:" + strlist[1];
                            dispstr = dispstr + DispErrInfo(strlist[1]);
                        }
                        if (strlist.length > 2) {
                            dispstr = dispstr + "设备编号:" + strlist[2] + "\r\n";
                        }
                        returninfo.value = dispstr;
                        break;
                    
                    case "getmifareversion":
                        dispstr = "函数名称:" + strlist[0] + "\r\n";
                        if (strlist[1] == "ReturnCode:000") {
                            dispstr = dispstr + "操作结果:" + strlist[1];
                            dispstr = dispstr + ",读取IC卡型号成功!\r\n";
                            dispstr = dispstr + "ATQA:" + strlist[2] + "\r\n";
                            dispstr = dispstr + "SAK:" + strlist[3] + "\r\n";
                            dispstr = dispstr + "型号:" + strlist[4] + "\r\n";
                        } else {
                            dispstr = dispstr + "操作结果:" + strlist[1];
                            dispstr = dispstr + DispErrInfo(strlist[1]);
                        }
                        if (strlist.length > 5) {
                            dispstr = dispstr + "Version:" + strlist[5] + "\r\n";
                        }
                        returninfo.value = dispstr;
                        break;

                    case "cpurequest1":
                        dispstr = "函数名称:" + strlist[0] + "\r\n";
                        if (strlist[1] == "ReturnCode:000" || strlist[1] == "ReturnCode:052") {
                            dispstr = dispstr + "操作结果:" + strlist[1];
                            dispstr = dispstr + ",卡已激活!\r\n";
                            dispstr = dispstr + "16进制卡号:" + strlist[2] + "\r\n";
                            dispstr = dispstr + "10进制卡号:" + strlist[3] + "\r\n";
                            dispstr = dispstr + "卡片参数:" + strlist[4] + "\r\n";
                            dispstr = dispstr + "卡片版本:" + strlist[5] + "\r\n";
                            dispstr = dispstr + "厂家代码:" + strlist[6] + "\r\n";
                            if (strlist.length > 8) {
                                dispstr = dispstr + "ATQA:" + strlist[7] + "\r\n";
                                dispstr = dispstr + "SAK:" + strlist[8] + "\r\n";
                            }
                            carduid.value = strlist[2];
                        } else {
                            dispstr = dispstr + "操作结果:" + strlist[1];
                            dispstr = dispstr + DispErrInfo(strlist[1]);
                        }
                        returninfo.value = dispstr;
                        break;

                    case "cpuisoapdu":
                        dispstr = "函数名称:" + strlist[0] + "\r\n";
                        if (strlist[1] == "ReturnCode:000") {
                            dispstr = dispstr + "操作结果:" + strlist[1];
                            dispstr = dispstr + ",返回代码:" + strlist[2];
                            dispstr = dispstr + ",代码说明:" + ReturnCodeDes(strlist[2]);
                        } else {
                            dispstr = dispstr + "操作结果:" + strlist[1];
                            dispstr = dispstr + DispErrInfo(strlist[1]);
                        }
                        returninfo.value = dispstr;
                        break;

                    case "desfireauthkeyev2":
                        dispstr = "执行函数名称:" + strlist[0] + " 认证标签密钥操作\r\n";
                        if (strlist[1] == "ReturnCode:000") {
                            dispstr = dispstr + "操作结果:" + strlist[1];
                            dispstr = dispstr + ",返回代码:" + strlist[2];
                            dispstr = dispstr + ",代码说明:" + ReturnCodeDes(strlist[2]);
                        } else {
                            dispstr = dispstr + "操作结果:" + strlist[1];
                            dispstr = dispstr + ",返回代码:" + strlist[2];
                            dispstr = dispstr + ",代码说明:" + ReturnCodeDes(strlist[2]);
                            if (strlist[2] == "9140") {
                                dispstr = dispstr + ",NTAG424卡建议选择上面的 【424卡的ISO DF Name】后执行【第二步:选择应用】后再认证。";
                            }
                        }
                        returninfo.value = dispstr;
                        break;

                    case "ntagchangkey":
                        dispstr = "执行函数名称:" + strlist[0] + " 更改标签密钥操作\r\n";
                        dispstr = dispstr + "函数返回结果:" + strlist[1] + "\r\n"
                        dispstr = dispstr + "卡片返回代码:" + strlist[2] + "\r\n"
                        if (strlist[2] == "91AE") {
                            dispstr = dispstr + "返回代码说明:更改密码指令被禁止或密码未认证或密码不对,请先用0号密码认证后再试!\r\n"
                        } else {
                            dispstr = dispstr + "返回代码说明:" + strlist[3] + "\r\n"
                        }                        
                        returninfo.value = dispstr;
                        break; 

                    case "ntagsetconfiguration":
                        dispstr = "执行函数名称:" + strlist[0] + " 更改标签配置操作\r\n";
                        dispstr = dispstr + "函数返回结果:" + strlist[1] + "\r\n"
                        dispstr = dispstr + "卡片返回代码:" + strlist[2] + "\r\n"
                        if (strlist[2] == "91AE") {
                            dispstr = dispstr + "返回代码说明:更改为随机UID指令被禁止或密码未认证或密码不对,请先用正确的密码号进行认证再试!\r\n"
                        } else {
                            dispstr = dispstr + "返回代码说明:" + strlist[3] + "\r\n"
                        }
                        returninfo.value = dispstr;
                        break;

                    case "forumtype4_write_ndeftag":
                        dispstr = "函数名称:" + strlist[0] + "\r\n";
                        if (strlist[1] == "ReturnCode:000") {
                            dispstr = dispstr + "操作结果:" + strlist[1] + ",写入标签成功!\r\n";                            
                            dispstr = dispstr + "标签号码:" + strlist[2];
                        } else {
                            dispstr = dispstr + "操作结果:" + strlist[1] + DispErrInfo(strlist[1]);
                        }
                        returninfo.value = dispstr;
                        break;

                    case "forumtype4getuid":
                        dispstr = "函数名称:" + strlist[0] + "\r\n";
                        if (strlist[1] == "ReturnCode:000") {
                            dispstr = dispstr + "操作结果:" + strlist[1] + ",读取标签真实UID成功!\r\n";
                            dispstr = dispstr + "标签号码:" + strlist[2];
                        } else {
                            dispstr = dispstr + "操作结果:" + strlist[1] + DispErrInfo(strlist[1]);
                        }
                        returninfo.value = dispstr;
                        break;

                    case "forumtype4_read_ndeftag":
                        dispstr = "函数名称:" + strlist[0] + "\r\n";
                        if (strlist[1] == "ReturnCode:000") {
                            dispstr = dispstr + "操作结果:" + strlist[1] + ",读取标签NDEF记录成功!\r\n";
                            dispstr = dispstr + "标签号码:" + strlist[2] + "\r\n";
                            dispstr = dispstr + strlist[3] ;
                        } else {
                            dispstr = dispstr + "操作结果:" + strlist[1] + DispErrInfo(strlist[1]);
                        }
                        returninfo.value = dispstr;
                        break;

                    case "ntagreadfilesettings":
                        dispstr = "函数名称:" + strlist[0] + "\r\n";
                        if (strlist[1] == "ReturnCode:000") {
                            dispstr = dispstr + "操作结果:" + strlist[1] + ",读取标签配置信息!\r\n";
                            dispstr = dispstr + "返回代码:" + strlist[2] + "\r\n";
                            dispstr = dispstr + "配置信息:" + strlist[3] + "\r\n";
                            text_setup.value = strlist[3];
                        } else {
                            dispstr = dispstr + "操作结果:" + strlist[1] + DispErrInfo(strlist[1]);
                        }
                        returninfo.value = dispstr;
                        break;

                    case "ntagchangefilesettings":
                        dispstr = "执行函数名称:" + strlist[0] + " 更改标签配置操作\r\n";
                        dispstr = dispstr + "函数返回结果:" + strlist[1] + "\r\n";
                        dispstr = dispstr + "卡片返回代码:" + strlist[2] + "\r\n";
                        if (strlist[2] == "91AE") {
                            if (select_RWsetconnmodel.selectedIndex == 1) {
                                dispstr = dispstr + "返回代码说明:更改指令被禁止或密码未认证或密码不对,请先用正确的密码号进行认证再试!\r\n";
                            } else {
                                dispstr = dispstr + "返回代码说明:更改指令被禁止或不支持明文操作,请先用正确的密码号进行认证并且选择"密文+MAC保护的通信模式"再试!\r\n";
                            }
                        } else {
                            dispstr = dispstr + "返回代码说明:" + strlist[3] + "\r\n";
                        }
                        returninfo.value = dispstr;
                        break;
                    
                }
            }
            ButtonEnabled();  //恢复按键的onclick事件
        }

        function WebSocketRun(sendinfo) {   //websockket发送指令
            iswsrun = false;

            try {
                if ("WebSocket" in window) {
                    ws = new WebSocket(wsUri);
                }
                else if ("MozWebSocket" in window) {
                    ws = new MozWebSocket(wsUri);
                }
                else {
                    ButtonEnabled();  //恢复按键的onclick事件
                    received_msg = "您的浏览器不支持WebSocket,请选用支持WebSocket的浏览器!";
                    return;
                }

                clearTimeout(mytimer);

                ws.onopen = function (evt) {
                    ws.send(sendinfo);
                    iswsrun = true;

                    if (sendinfo == 'NDEF_Clear,' || sendinfo == 'NDEF_BuffWriteTag,') {
                        mytimer = setTimeout("timeoutevent()", 5000);	//清除标签的时间要长
                    } else { mytimer = setTimeout("timeoutevent()", 2000); }
                };

                ws.onmessage = WebSocketRev;

                ws.onerror = function (e) {
                    if (iswsrun != true) {
                        received_msg = "请先在当前电脑下载>安装>运行我们的服务程序......";
                        window.open("http://www.bossknow.cn:90/RongShiWebReaderTest/RFIDWebPluginSetup_Windows.rar", "top");//打开新窗口
                        ButtonEnabled();  //恢复按键的onclick事件
                        alert("请先下载>安装>运行我们的服务程序,再刷新本页面......");
                    }
                };

            }
            catch (ex) {
                if (iswsrun != true) {
                    received_msg = "请先在当前电脑下载>安装>运行我们的服务程序......";
                    window.open("http://www.bossknow.cn:90/RongShiWebReaderTest/RFIDWebPluginSetup_Windows.rar", "top");//打开新窗口
                    ButtonEnabled();  //恢复按键的onclick事件
                    alert("请先下载>安装>运行我们的服务程序,再刷新本页面......");
                }
            }
        }

    </script>


<style>
*{box-sizing:border-box;font-family:"Microsoft Yahei",SimSun,system-ui;font-size:13px;}
body{background:#ececec;margin:8px;}
.win-container{
  background:#f0f0f0;
  border:1px solid #999;
  padding:10px;
  max-width:1400px;
}
button{
  padding:6px 12px;
  border:1px solid #666;
  background:#f8f8f8;
  border-radius:3px;
  cursor:pointer;
}
button.green{background:#39d060;color:#000;font-weight:bold;}
button.cyan{background:#72e0f5;}
input[type=text]{
  padding:4px;
  border:1px solid #999;
  background:#fff;
}
select{padding:3px;border:1px solid #999;}
.warn-yellow{
  background:#fff260;
  color:#000;
  padding:4px 6px;
  margin:6px 0;
  font-weight:bold;
}
.row{display:flex;gap:8px;align-items:center;margin:6px 0;flex-wrap:wrap;}
.col-block{border:1px solid #aaa;padding:8px;margin:6px 0;background:#f7f7f7;}
.red-text{color:#c00000;font-weight:bold;}
</style>

</head>
<body>
    <div align="center">
        <div class="win-container">
            <h3 style="margin:0 0 8px 0;">Ntag 424 DNA标签读写</h3>

            <div class="row">
                <button style="width:200px" id="butt_beep" onclick="beepDevice()">让设备发出声响</button>
                <button id="butt_getdevnum" onclick="getdevicenumber()">读出设备全球唯一的设备编号,作为加密狗用</button>
                <div style="margin-left:auto;">
                    <button id="butt_getcardtype" onclick="geticcardtype()">获取IC卡芯片型号</button>
                </div>
            </div>

            <div class="row">
                <button style="width:200px" id="butt_cpurequest1" onclick="cpu_cpurequest1()">第一步:激活 Ntag 424</button>
                <span>16进制卡号:</span>
                <input type="text" id="carduid" style="width:200px;">
                <span class="warn-yellow red-text">注:每次拿开卡重放后都需要激活,才能驱动卡进入14443‑4协议状态。</span>
            </div>

            <div class="row">
                <button style="width:200px" id="butt_selectappid" onclick="selectappid()">第二步:选择卡内已有的应用</button>
                <span>选择卡内应用:</span>
                <select id="seleappid" onchange="changeapp()">
                    <option selected="selected">424卡的ISO MF Name</option>
                    <option>424卡的ISO File ID(3F00)</option>
                    <option>424卡的ISO DF Name</option>
                    <option>424卡的ISO File ID(E110)</option>
                </select>

                <select id="selefileid">
                    <option>ISO DF/MF Name</option>
                    <option>ISO FileID</option>
                </select>

                <select id="selefci">
                    <option>Return FCI</option>
                    <option>no FCI</option>
                </select>

                <span>16进制目标:</span>
                <input type="text" id="objedata" value="D2 76 00 00 85 01 00" style="width:350px;" onkeyup="this.value=this.value.replace(/[^0-9a-fA-F ]/g,'')">
            </div>

            <div class="row">
                <button style="width:200px" id="butt_desfireauthkeyev2" onclick="desfireauthkeyev2()">密钥认证</button>
                <span>认证密钥:</span>
                <select id="selectauthkey">
                    <option selected="selected">0</option>
                    <option>1</option>
                    <option>2</option>
                    <option>3</option>
                    <option>4</option>
                </select>
                <span>16进制旧认证密钥:</span>
                <input type="text" id="text_authkey" value="00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" style="width:420px;" onkeyup="this.value=this.value.replace(/[^0-9a-fA-F ]/g,'')">
                <span>加解密方法:</span>
                <select id="selectdecnec">
                    <option selected="selected">EV2First(命令71h)</option>
                    <option>EV2NonFirst(命令77h)</option>
                </select>
            </div>

            <div class="row">
                <button style="width:200px" id="butt_ntagchangkey" onclick="ntagchangkey()">更改密钥</button>
                <span>更改密钥:</span>
                <select id="selectnewkey">
                    <option>0</option>
                    <option selected>1</option>
                    <option>2</option>
                    <option>3</option>
                    <option>4</option>
                </select>
                <span style="margin-left:27px;">16进制新密钥:</span>
                <input type="text" id="text_newkey" value="00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" style="width:420px;" onkeyup="this.value=this.value.replace(/[^0-9a-fA-F ]/g,'')">
            </div>

            <div class="row">
                <button id="butt_ntagsetconfiguration" onclick="ntagsetconfiguration()">将424卡配置成随机 UID 模式</button>
                <span class="warn-yellow red-text">注:424卡更改为随机UID模式后,此卡将永久为随机模式!!!</span>
            </div>            

            <div class="col-block">
                <strong>Ntag 424 DNA卡写入NDEF URI记录</strong>
                <div class="row">
                    <button id="butt_examples1" onclick="examples1()">例子1:动态UID(可解析出真正的UID)</button>
                    <button id="butt_examples2" onclick="examples2()">例子2:直接UID和计数器</button>
                    <button id="butt_examples3" onclick="examples3()">例子3:动态UID+加密数据+MAC</button>
                    <div style="margin-left:auto;">
                        <span>光标处的偏移量:</span>
                        <input type="text" id="text_selestar" style="width:100px;">
                    </div>
                </div>

                <div class="row">
                    <span>标题名称:</span>
                    <input type="text" id="text_title" value="百度" style="width:100px;">
                    <span>前缀:</span>
                    <select id="select_prefix">
                        <option>无前缀</option>
                        <option>http://www.</option>
                        <option selected>https://www.</option>
                        <option>http://</option>
                        <option>https://</option>
                        <option>tel:</option>
                        <option>mailto:</option>
                        <option>ftp://anonymous:anonymous@</option>
                        <option>ftp://ftp.</option>
                        <option>ftps://</option>
                        <option>sftp://</option>
                        <option>smb://</option>
                        <option>nfs://</option>
                        <option>ftp://</option>
                        <option>dav://</option>
                        <option>news:</option>
                        <option>telnet://</option>
                        <option>imap:</option>
                        <option>rtsp://</option>
                        <option>urn:</option>
                        <option>pop:</option>
                        <option>sip:</option>
                        <option>sips:</option>
                        <option>tftp:</option>
                        <option>btspp://</option>
                        <option>btl2cap://</option>
                        <option>btgoep://</option>
                        <option>tcpobex://</option>
                        <option>irdaobex://</option>
                        <option>file://</option>
                        <option>urn:epc:id:</option>
                        <option>urn:epc:tag:</option>
                        <option>urn:epc:pat:</option>
                        <option>urn:epc:raw:</option>
                        <option>urn:epc:</option>
                        <option>urn:nfc:</option>
                    </select>

                    <input type="text" id="text_uri" value="baidu.com" style="flex:1;box-sizing:border-box;" onclick="getCaretPos()">
                </div>

                <div class="row">
                    <label><input type="checkbox" id="check_RWAuthKey"> 读写卡片需要认证密码,密码号:</label>
                    <select id="select_RWAuthKeyId">
                        <option>0</option>
                        <option>1</option>
                        <option>2</option>
                        <option selected>3</option>
                        <option>4</option>
                    </select>
                    <span>16进制认证密钥:</span>
                    <input style="width:380px;" type="text" id="text_RWauthkey" value="00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" onkeyup="this.value=this.value.replace(/[^0-9a-fA-F ]/g,'')">
                    <span>通信模式:</span>
                    <select id="select_RWCommMode">
                        <option selected>明文</option>
                        <option>MAC保护</option>
                        <option>密文+MAC保护</option>
                    </select>
                    <button class="cyan" id="butt_forumtype4_write_ndeftag_uri" onclick="forumtype4_write_ndeftag_uri()">将URI网址写入424DNA卡</button>
                    
                </div>

                <div class="row">
                    <label><input type="checkbox" id="check_AnalyzeImage"> 解析镜像,SDM元 数据读取密钥:</label>
                    <input type="text" id="text_SDMkey" value="00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" style="width:365px;" onkeyup="this.value=this.value.replace(/[^0-9a-fA-F ]/g,'')">
                    <span>CMAC验证密钥:</span>
                    <input type="text" id="text_CMACkey" value="00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" style="width:365px;" onkeyup="this.value=this.value.replace(/[^0-9a-fA-F ]/g,'')">
                    <button id="butt_forumtype4getuid" onclick="forumtype4getuid()">读取卡片真实UID</button>
                    <button class="green" id="butt_forumtype4_read_ndeftag" onclick="forumtype4_read_ndeftag()">读取卡内NDEF记录</button>
                </div>
            </div>

            <div class="warn-yellow">更改或读取文件配置(2号文件,为Standard Data File或 NDEF File,默认通信模式为明文)</div>

            <div class="col-block">
                <div class="row">
                    <span>通讯模式:</span>
                    <select id="select_SetCommMode">
                        <option selected>明文</option>
                        <option>MAC保护</option>
                        <option>密文+MAC保护</option>
                    </select>
                    <span class="red-text">首选明文通讯,尽量不要更改这里!!!</span>
                </div>

                <div class="row">
                        <span style="margin-left:100px;">只读指令需要先认证的密码:</span>
                        <select id="select_readonlykey">
                            <option>0</option>
                            <option>1</option>
                            <option>2</option>
                            <option>3</option>
                            <option>4</option>
                            <option selected>无需密码</option>
                            <option>禁止操作</option>
                        </select>

                        <span style="margin-left:50px;">只写指令需要先认证的密码:</span>
                        <select id="select_writeonlykey">
                            <option>0</option>
                            <option>1</option>
                            <option>2</option>
                            <option>3</option>
                            <option>4</option>
                            <option selected>无需密码</option>
                            <option>禁止操作</option>
                        </select>

                        <span style="margin-left:50px;">读写指令需要先认证的密码:</span>
                        <select id="select_readwritekey">
                            <option>0</option>
                            <option>1</option>
                            <option>2</option>
                            <option>3</option>
                            <option>4</option>
                            <option selected>无需密码</option>
                            <option>禁止操作</option>
                        </select>

                        <div style="margin-left:50px;">
                            <span>更改指令需要先认证的密码:</span>
                            <select id="select_changesetkey">
                                <option>0</option>
                                <option>1</option>
                                <option>2</option>
                                <option>3</option>
                                <option>4</option>
                                <option selected>无需密码</option>
                            </select>
                        </div>
                    </div>

                <div align="right" >
                    <div class="red-text">
                        注意:更改指令需要先认证的密码如设为禁止操作,以后将不能用5F指令更改配置,如设为无需密码,下次更改配置需要用明文的通讯模式!
                    </div>
                </div>


                <div align="left">
                    <label><input type="checkbox" id="check_SDMMirrorImageEn"> 启用SDM镜像</label>

                        <div class="row">
                            <label style="margin-left:50px;"><input type="checkbox" id="check_UIDMirrorImageEn"> 启用UID镜像</label>

                            <span>SDM元数据读取访问权限:</span>
                            <select id="select_SDMRead">
                                <option>0</option>
                                <option>1</option>
                                <option>2</option>
                                <option>3</option>
                                <option>4</option>
                                <option selected>无需密码</option>
                                <option>禁止操作</option>
                            </select>
                            <span style="margin-left:90px;">UID镜像位置:</span>
                            <input type="text" value="0" style="width:70px;" id="text_UIDMirrorImage">
                            <span style="margin-left:50px;">PICCDataOffset:</span>
                            <input type="text" value="0" style="width:70px;" id="text_PICCDataOffset">
                        </div>

                        <div class="row">
                            <span style="margin-left:150px;">面向CMAC计算的派生密钥:</span>
                            <select id="select_CMACCalc">
                                <option>0</option>
                                <option>1</option>
                                <option>2</option>
                                <option>3</option>
                                <option>4</option>
                                <option selected>禁止操作</option>
                            </select>
                            <span style="margin-left:45px;">SDMMACInputOffset:</span>
                            <input type="text" value="0" style="width:70px;" id="text_SDMMACInputOffset">
                            <span style="margin-left:50px;">SDMMACoffset:</span>
                            <input type="text" value="0" style="width:70px;" id="text_SDMMACoffset">
                            
                        </div>

                        <div class="row">
                            <label style="margin-left:50px;"><input type="checkbox" id="check_CounMirrorImageEn"> 启用计数器镜像</label>
                            <span style="margin-left:10px;">SDM计数器检索密钥:</span>
                            <select id ="select_SDMCount">
                                <option>0</option>
                                <option>1</option>
                                <option>2</option>
                                <option>3</option>
                                <option>4</option>
                                <option>无需密码</option>
                                <option selected>禁止操作</option>
                            </select>
                            <span style="margin-left:75px;">计数器数据位置:</span>
                            <input type="text" value="0" style="width:70px;" id="text__Counoffset">
                        </div>

                        <div class="row">
                            <label style="margin-left:50px;"><input type="checkbox" id="check_CounLimitEn"> 启用计数器限额</label>
                            <span style="margin-left:55px;">计数器限额值:</span>
                            <input type="text" value="0" style="width:80px;" id="text_CounLimit">
                            <span class="red-text">当计数器的值达到计数器限额值时,或计数器的值达到16777215时,读ndef文件时将返回错误!</span>
                        </div>

                        <div class="row">
                            <label style="margin-left:50px;"><input type="checkbox" id="check_SDMENCFileData"> SDMENCFileData</label>
                            <span style="margin-left:34px;">SDMENCOffset:</span>
                            <input type="text" value="0" style="width:80px;" id="text_SDMENCOffset">
                            <span style="margin-left:75px;">SDMENCLength:</span>
                            <input type="text" value="0" style="width:70px;" id="text_SDMENCLength">                            
                        </div>

                        <div class="row">
                            <button style="display:none" id="butt_getcountervalue" onclick="getcountervalue()">读取卡片计数器值</button>

                            <button id="butt_ntagreadfilesettings" onclick="ntagreadfilesettings()">读取卡片配置信息</button>
                            <span>本次操作的通信模式:</span>
                            <select id="select_RWsetconnmodel">
                                <option>明文</option>
                                <option>密文+MAC保护</option>
                            </select>
                            <span>卡配置信息:</span>
                            <input type="text" style="width:500px;" id="text_setup" onkeyup="this.value=this.value.replace(/[^0-9a-fA-F ]/g,'')">
                            <div style="margin-left:auto;">
                                <button class="cyan" id="butt_ntagchangefilesettings" onclick="ntagchangefilesettings()">更改卡片配置信息</button>
                            </div>
                        </div>
            </div>

            <div>
                <textarea style="color:blue;width:100%" name="returninfo" id="returninfo" cols="140" rows="13"></textarea>
            </div>

        </div>

       </div>

   </div>

    <p align="center">以上功能需要插件支持,在发送读卡、写卡操作请求之前,请先确保您的电脑已安装并运行我们的读写器插件:   <a href="http://www.bossknow.cn:90/RongShiWebReaderTest/RFIDWebPluginSetup_Windows.rar"> RFIDWebPlugin</a> </p>
    <p align="center"><a href="http://www.bossknow.cn:90/RongShiWebReaderTest/RFIDWebPluginSetup.html">如何防止RFIDWebPlugin插件被杀毒软件误报删除</a></p>
</body>
</html>
相关推荐
宁风2 小时前
JavaScript:函数体系-1
前端·javascript
oooo_z3 小时前
美股历史K线数据API接口选型指南:iTick覆盖1分钟到月线全周期
服务器·前端·javascript
mONESY3 小时前
LangChain 结构化输出三兄弟:ToolCall、OutputParser、withStructuredOutput 彻底讲透
javascript
知兀4 小时前
【前端】受控和非受控组件
前端·javascript·react
晴天164 小时前
JavaScript 与 Java 垃圾回收机制对比
java·开发语言·javascript
huali4 小时前
vue-split-screen:让 Vue Router 的导航轨迹变成两个页面
前端·javascript·vue.js
bug总结4 小时前
uniapp总结
开发语言·前端·javascript
走到天涯海角4 小时前
pinia和Vuex的区别以及使用pinia
开发语言·前端·javascript
晴天165 小时前
Web 页面内存溢出与 CPU 溢出:区别、诊断与最佳实践
前端·javascript