JavaScript读写NFC Ntag标签源码

发布时间:2023年12月21日

https://item.taobao.com/item.htm?spm=a1z10.5-c-s.w4002-21818769070.35.74185b43tGWQH5&id=562957272162

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>NFC_Ntag卡读写DEMO</title>

    <script language="javascript">
        var EXTERNKEY = 0x10;    //需要认证卡片密钥
		
        var iswsrun = false;
        var ws;
        var received_msg = "";
        var mytimer;
        var strls = "";
        var errorno = "";

        var wsUri = "ws://127.0.0.1:39189";   //端口号必须与RFIDWebServer端口一致
		
        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 beep() {				     //驱动发卡器响声令
            textarea.value = "";		
            WebSocketRun("pcdbeep,30");					
        }
		
        function getdevicenumber() {         //读取发卡器唯一出厂序号,可以当加密狗使用			
            textarea.value = "";		
			serialnumber.value="";
            WebSocketRun("pcdgetdevicenumber");			
        }			
		
        function piccrequest_ul() {
            var RequestCardComm = "piccrequest_ul,";
            WebSocketRun(RequestCardComm);
        }				
		
        function piccinit_ntag() {
            textarea.value = "";
            myctrlword = 0; 							//指定控制字,无需密码为0,当需要密码时为EXTERNKEY;
			
            mypiccserial = "00000000000000";  			//指定序列号,00000000000000 表示任意 NTAG卡。
			
            if (checkauth.checked) {			     	//指定密码,NTAG21x卡密码为4个字节,卡出厂时密码功能不启用,这样无需密码也能读写卡
                myctrlword = EXTERNKEY;              	//指定控制字,无需密码为0,当需要密码时为EXTERNKEY;
                mypicckey = authkey0.value.trim();
                if (!isHex(mypicckey) || mypicckey.length!=8) {
                    alert( "卡片认证密钥输入错误,请输入8位16进制密钥!");
                    authkey0.focus();
                    authkey0.select();
                    return;
                }
            }
            else {
                mypicckey = "00000000";               	
            }
			
            //数据准备
            if (selonoff.selectedIndex == 0) {			//开启密码保护功能,写保护功能生效,但读保护需要下面的数据设定                
                newkeystr = newkey.value.trim();		//取新密码
                if (!isHex(newkeystr) || newkeystr.length != 8) {
                    alert( "新密钥输入错误,请输入8位16进制新密钥!");
                    newkey.focus();
                    newkey.select();
                    return;
                }

                strls1 = protectpageno.value.trim();//起始保护页号
                if (!isUIntNum(strls1)) {
                    alert("起始保护页号输入错误!");
                    protectpageno.focus();
                    protectpageno.select();
                    return;
                }
                strls1 = "0" + parseInt(strls1).toString(16);
                beginpage = strls1.substring(strls1.length - 2);	
							                
                //计数器
                strls1 = keyerrortimes.value.trim();//允许密码错误次数
                if (!isUIntNum(strls1)) {
                    alert("允许密码错误次数输入错误!");
                    protectpageno.focus();
                    protectpageno.select();
                    return;
                }
                i = parseInt(strls1);
                i = i % 8;
                if (checkreadon.checked) {
                    i = i + 128;
                }
                strls1 = "0" + i.toString(16);
                authfail = strls1.substring(strls1.length - 2);
				
                packstr = packcode.value.trim();		//取PACK码
                if (!isHex(packstr) || packstr.length != 4) {
                    alert( "PACK密钥确认码输入错误,请输入4位16进制PACK密钥确认码!");
                    packcode.focus();
                    packcode.select();
                    return;
                }				
				
				mypiccdata = "000000";
				mypiccdata = mypiccdata +beginpage;
                mypiccdata = mypiccdata + authfail;
                mypiccdata = mypiccdata + "000000";
                mypiccdata = mypiccdata + newkeystr;         //4字节新密码
                mypiccdata = mypiccdata + packstr;			 //2字节PACK确认码	
				mypiccdata = mypiccdata + "0000";
				
				myctrlword = myctrlword + 0x01; //更新控制字
                myctrlword = myctrlword + 0x02; //更新控制字
                myctrlword = myctrlword + 0x04; //更新控制字
            }
            else {
                mypiccdata = "000000FF";		//MIRROR,RFUI,MIRROR_PAGE,AUTH0
                myctrlword = myctrlword + 0x01; //更新控制字
                mypiccdata = mypiccdata + "000000000000000000000000";
                myctrlword = myctrlword + 0x02; //更新控制字
            }			
			
            var WriteNtagComm = "piccinit_ntag," + myctrlword + "," + mypiccserial + "," + mypicckey + "," + mypiccdata;
            WebSocketRun(WriteNtagComm);
        }
		
        function readcard_ntag() {
            textarea.value = "";
			carduid.value="";
            RWdata.value="";

            mypiccserial = "00000000000000";         	//指定序列号,未知卡序列号时可指定为14个0,因为NTAG21x卡是7个字节的卡序列号
            
            if (checkauth.checked) {			     	//指定密码,NTAG21x卡密码为4个字节,卡出厂时密码功能不启用,这样无需密码也能读写卡
                myctrlword = EXTERNKEY;              	//指定控制字,无需密码为0,当需要密码时为EXTERNKEY;
                mypicckey = authkey0.value.trim();
                if (!isHex(mypicckey) || mypicckey.length!=8) {
                    alert( "卡片认证密钥输入错误,请输入8位16进制密钥!");
                    authkey0.focus();
                    authkey0.select();
                    return;
                }
            }
            else {
                mypicckey = "00000000";
                myctrlword = 0;                      	//指定控制字,无需密码为0,当需要密码时为EXTERNKEY;
            }

            myblockaddr = ntagstartno.value.trim();  	//读写起始页
            if (!isUIntNum(myblockaddr)) {
                alert( "读写起始页输入错误!");
                ntagstartno.focus();
                ntagstartno.select();
                return;
            }

            myblocksize = ntagpagenumber.value.trim();	//读写页数
            if (!isUIntNum(myblocksize)) {
                alert( "读写页数输入错误!");
                ntagpagenumber.focus();
                ntagpagenumber.select();
                return;
            }

            var ReadNtagComm = "piccreadex_ntag," + myctrlword + "," + mypiccserial + "," + mypicckey + "," + myblockaddr + "," + myblocksize;
            WebSocketRun(ReadNtagComm);
        }		
		
        function writecard_ntag() {
            textarea.value = "";
			carduid.value="";

            mypiccserial = "00000000000000";         	//指定序列号,未知卡序列号时可指定为14个0,因为NTAG21x卡是7个字节的卡序列号
            
            if (checkauth.checked) {			     	//指定密码,NTAG21x卡密码为4个字节,卡出厂时密码功能不启用,这样无需密码也能读写卡
                myctrlword = EXTERNKEY;              	//指定控制字,无需密码为0,当需要密码时为EXTERNKEY;
                mypicckey = authkey0.value.trim();
                if (!isHex(mypicckey) || mypicckey.length!=8) {
                    alert( "卡片认证密钥输入错误,请输入8位16进制密钥!");
                    authkey0.focus();
                    authkey0.select();
                    return;
                }
            }
            else {
                mypicckey = "00000000";
                myctrlword = 0;                      	//指定控制字,无需密码为0,当需要密码时为EXTERNKEY;
            }

            myblockaddr = ntagstartno.value.trim();  	//读写起始页
            if (!isUIntNum(myblockaddr)) {
                alert( "读写起始页输入错误!");
                ntagstartno.focus();
                ntagstartno.select();
                return;
            }

            myblocksize = ntagpagenumber.value.trim();	//读写页数
            if (!isUIntNum(myblocksize)) {
                alert( "读写页数输入错误!");
                ntagpagenumber.focus();
                ntagpagenumber.select();
                return;
            }

            //数据
            strls = RWdata.value.trim();
            if (!isHex(strls)  || strls.length<myblocksize*8) {
                alert( "读写数据输入错误,请输入"+(myblocksize*8).toString()+"位16进制写卡数据!");
                RWdata.focus();
                RWdata.select();
                return;
            }

            var WriteNtagComm = "piccwriteex_ntag," + myctrlword + "," + mypiccserial + "," + mypicckey + "," + myblockaddr + "," + myblocksize + "," + strls;
            WebSocketRun(WriteNtagComm);
        }			
		
		function DispErrInfo(errcode){
            var errstr = "";
            switch (errcode) {
                case "ReturnCode:008":
                case "ReturnCode:009":
                case "ReturnCode:010":
                    errstr = ",未寻到卡,请将卡放到发卡器的感应区!";
                    break;
                case "ReturnCode:011":
                case "ReturnCode:012":
                    errstr = ",卡密码认证失败!";
                    break;
                case "ReturnCode:013":
                    errstr = ",读卡失败,可能需要验证密码!";
                    break;
                case "ReturnCode:014":
                    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:444":
                    errstr = ",RFIDWebServer系统文件错误!";
                    break;
                default:
                    errstr = ",未知的错误!";
            }
            return errstr;
		}			
		
		
        window.onerror = function (e) {
            alert("不好意思,出错了!");
            return true;//屏蔽系统事件
        }

        function timeoutevent() {
            ws.close();
            textarea.value = "websockket返回超时";
        }

        //websockket数据处理
        function WebSocketRev(evt) {
            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];
                            dispstr = dispstr + ",已执行蜂鸣响声操作!\r\n"
                        } else {
                            dispstr = dispstr + "操作结果:" + strlist[1];
                            dispstr = dispstr + DispErrInfo(strlist[1]);
                        }
                        textarea.value = dispstr;
                        break;

                    case "pcdgetdevicenumber":
                        dispstr = "函数名称:" + strlist[0] + "\r\n";
                        if (strlist[1] == "ReturnCode:000") {
                            dispstr = dispstr + "操作结果:" + strlist[1];
                            dispstr = dispstr + ",已读取设备编号!\r\n"
							serialnumber.value =  strlist[2] ;
                        } else {
                            dispstr = dispstr + "操作结果:" + strlist[1];
                            dispstr = dispstr + DispErrInfo(strlist[1]);
                        }
                        textarea.value = dispstr;
                        break;

                    case "piccrequest_ul":
                        dispstr = "函数名称:" + strlist[0] + "\r\n";
                        if (strlist[1] == "ReturnCode:000") {
                            dispstr = dispstr + "操作结果:" + strlist[1];
                            dispstr = dispstr + ",已读取NFC Ntag卡UID号!\r\n";
							carduid.value=strlist[2];							
                        } else {
                            dispstr = dispstr + "操作结果:" + strlist[1];
                            dispstr = dispstr + DispErrInfo(strlist[1]);
                        }
                        textarea.value = dispstr;
                        break;
						
                    case "piccinit_ntag":
                        dispstr = "函数名称:" + strlist[0] + "\r\n";
                        if (strlist[1] == "ReturnCode:000") {
                            dispstr = dispstr + "操作结果:" + strlist[1];
                            dispstr = dispstr + ",设置Ntag卡密钥机制成功!\r\n"
                        } else {
                            dispstr = dispstr + "操作结果:" + strlist[1];
                            dispstr = dispstr + DispErrInfo(strlist[1]);
                        }
                        if (strlist.length > 2) {
                            carduid.value=strlist[2];	
                        }
                        textarea.value = dispstr;
                        break;		
						
                    case "piccreadex_ntag":
                        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) {
							carduid.value=strlist[2];
                        }
                        if (strlist.length > 3) {
                            RWdata.value= strlist[3];
                        }
                        textarea.value = dispstr;
                        break;	
						
					case "piccwriteex_ntag":
                        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) {
                            carduid.value=strlist[2];	
                        }
                        textarea.value = dispstr;
                        break;																										
                }
            }
        }		
		
        function WebSocketRun(sendinfo) {
            iswsrun = false;

            try {
                if ("WebSocket" in window) {
                    ws = new WebSocket(wsUri);
                }
                else if ("MozWebSocket" in window) {
                    ws = new MozWebSocket(wsUri);
                }
                else {
                    received_msg = "您的浏览器不支持WebSocket,请选用支持WebSocket的浏览器!";
                    return;
                }

                clearTimeout(mytimer);

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

                    mytimer = setTimeout("timeoutevent()", 2000);
                };

                ws.onmessage = WebSocketRev;

                ws.onerror = function (e) {
                    if (iswsrun != true) {
                        received_msg = "请先在当前电脑下载>安装>运行我们的服务程序......";
                        window.open("http://www.icmcu.com/ICID15693-02V2test/RFIDWebServerSetup.exe", "top");//打开新窗口

                        alert("请先下载>安装>运行我们的服务程序,再刷新本页面......");
                    }
                };
            }
            catch (ex) {
                if (iswsrun != true) {
                    received_msg = "请先在当前电脑下载>安装>运行我们的服务程序......";
                    window.open("http://www.icmcu.com/ICID15693-02V2test/RFIDWebServerSetup.exe", "top");//打开新窗口

                    alert("请先下载>安装>运行我们的服务程序,再刷新本页面......");
                }
            }
        }
				
	</script>
</head>

<body>
<table width="866" height="487" border="1" align="center">
  <tr>
    <th width="124" height="45" scope="row"><input name="butt_beep" type="submit" id="butt_beep" onclick="beep()" value="驱动发卡器响声" /></th>
    <td width="716"><input name="butt_getdevnum" type="submit" id="butt_getdevnum" onclick="getdevicenumber()" value="读取发卡器唯一出厂序列号" />
      设备编号:
      <input name="serialnumber" type="text" id="serialnumber" size="8" maxlength="8" /></td>
  </tr>
  
  <tr>
    <th height="45" scope="row"><input name="butt_piccrequest_ul" type="submit" id="butt_piccrequest_ul" onclick="piccrequest_ul()" value="寻Ntag卡获取UID" /></th>
    <td>原始16进制卡号:
      <input name="carduid" type="text" id="carduid" size="14" maxlength="14" /></td>
  </tr>
  

  <tr>
    <th height="45" scope="row">&nbsp;</th>
    <td><p>
      <input type="checkbox" name="checkauth" id="checkauth" />
      
      选择先认证卡片密钥再继续以下的操作,16进制卡片认证密钥:
      <label for="authkey0"></label>
    <input name="authkey0" type="text" id="authkey0" value="12345678" size="8" maxlength="8" />
    </p></td>
  </tr>
  <tr>
    <th height="139" scope="row"><p>
      <input name="butt_piccinit_ntag" type="submit" id="butt_piccinit_ntag" onclick="piccinit_ntag()" value="设置卡片密钥机制" />
    </p></th>
    <td><p>
      <label for="rwtext"></label>
      <select name="selonoff" id="selonoff">
        <option>开启卡片密钥保护功能</option>
        <option selected="selected">取消卡片密钥保护功能</option>
      </select>
    ,从:
    <input name="protectpageno" type="text" id="protectpageno" value="20" size="4" maxlength="4" onkeyup="this.value=this.value.replace(/\D/g,'')"/>
    页开始有密钥保护功能,
    <input type="checkbox" name="checkreadon" id="checkreadon" />
    选择开启读操作密钥保护。</p>
      <p>新密钥:
        <input name="newkey" type="text" id="newkey" value="12345678" size="8" maxlength="8" />
      ,允许密钥认证失败次数:
      <input name="keyerrortimes" type="text" id="keyerrortimes" value="0" size="2" maxlength="2" onkeyup="this.value=this.value.replace(/\D/g,'')"/>
      ,PACK密钥确认码:
      <input name="packcode" type="text" id="packcode" value="1234" size="4" maxlength="4" />
      </p>
    <p>警告:当密钥认证失败次数取值0表示不限制次数,大于设置值时卡片将会报废!</p></td>
  </tr>
  
  <tr>
    <th  height="100" scope="row"><p>
      <input name="butt_readcard_ntag" type="submit" id="butt_readcard_ntag" onclick="readcard_ntag()" value="轻松读Ntag卡" />
    </p>
    <p>&nbsp;</p>
    <p>
      <input name="butt_writecard_ntag" type="submit" id="butt_writecard_ntag" onclick="writecard_ntag()" value="轻松写Ntag卡" />
    </p></th>
    <td><p>读写起始页:
      <input name="ntagstartno" type="text" id="ntagstartno" value="4" size="4" maxlength="4" onkeyup="this.value=this.value.replace(/\D/g,'')"/>
    ,读写页数:
    <input name="ntagpagenumber" type="text" id="ntagpagenumber" value="10" size="2" maxlength="2" onkeyup="this.value=this.value.replace(/\D/g,'')"/>
    ,每次最多读12页、写11页。</p>
      <p>
        <textarea name="RWdata" id="RWdata" cols="100" rows="3" ></textarea>
    </p></td>  
  </tr>  
  
  <tr>
    <th height="78" scope="row"><p>操作提示</p></th>
    <td><textarea name="textarea" id="textarea" cols="100" rows="5" ></textarea></td>
  </tr>
</table>
</body>
</html>

?

文章来源:https://blog.csdn.net/zhangjin7422/article/details/135124695
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。