Web浏览器读写NFC Ntag标签

 本示例使用的发卡器:RS232串口USB转COM读写器IC卡发卡器WEB浏览器二次开发JS编程SDK-淘宝网 (taobao.com)

<!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" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Web Serial串口读写器Ntag卡示例 </title><script>		window.onload = function() {document.getElementById('butt_openserial').hidden=true;document.getElementById('butt_closeserial').hidden=true;document.getElementById('dispauthkey').hidden=true;document.getElementById('authkey0').hidden=true;}if ('serial' in navigator){}else{alert('您的浏览器不支持 Web Serial API,暂无法使用以下功能!');}		navigator.serial.onconnect =function event(){console.log("Serial port connected: ", event.target);}navigator.serial.ondisconnect =function event(){console.log("Serial port disconnected: ", event.target);}var BLOCK0_EN = 0x01;//读第一块的(16个字节)var BLOCK1_EN = 0x02;//读第二块的(16个字节)var BLOCK2_EN = 0x04;//读第三块的(16个字节)var NEEDSERIAL = 0x08;//仅读指定序列号的卡var EXTERNKEY = 0x10;//用明码认证密码,产品开发完成后,建议把密码放到设备的只写区,然后用该区的密码后台认证,这样谁都不知道密码是多少,需要这方面支持请联系var NEEDHALT = 0x20; //读/写完卡后立即休眠该卡,相当于这张卡不在感应区。要相重新操作该卡必要拿开卡再放上去var port = null;var reader = null;var reading = false;const getdata=new Uint8Array(1000);     //接收串口返回的数据var DataPoint=0;                        //接收数据指针var SendCode=0;                         //已发送的指令代码function isUIntNum(val) {var testval = /^\d+$/; // 非负整数return (testval.test(val));}function isHex(val) {var testval = /^(\d|[A-F]|[a-f])+$/; // 十六进制数判断return (testval.test(val));}async function SelectSerial(){try{port =await navigator.serial.requestPort();  // 弹出系统串口列表对话框,选择一个串口进行连接ports =await navigator.serial.getPorts();    // 获取已连接的授权过的设备列表document.getElementById('butt_openserial').hidden=false;				}catch (e){console.log(e);}}function updateInputData(data) {let array = new Uint8Array(data); // event.data.buffer就是接收到的inputreport包数据了//let hexstr = "";					for (const data of array) {//hexstr += (Array(2).join(0) + data.toString(16).toUpperCase()).slice(-2) + " "; // 将字节数据转换成(XX )形式字符串getdata[DataPoint]=data;DataPoint=DataPoint+1;}var crc=0;for(i=1;i<DataPoint;i++){   //校验接收数据,同时也解决数据分包上传的问题crc=crc^getdata[i];}if (crc==0 && DataPoint>1){                let hexstr = "";for (i=0;i<DataPoint;i++){hexstr=hexstr+getdata[i].toString(16).padStart(2, '0').toUpperCase()+" ";}ReceiveData.value += hexstr;		        var dispstr="";var cardnohex="";var datahex="";switch (SendCode) {case 1:   //驱动发卡器响声的回应dispstr = "发卡器已执行响声指令!" ; 		label_disp.innerText=dispstr;break;case 6:    //读Ntag卡的回应switch (getdata[1]){case 0x00:for (i=2;i<=8;i++){cardnohex=cardnohex+getdata[i].toString(16).padStart(2, '0').toUpperCase();}for (i=11;i<DataPoint-1;i++){datahex=datahex+getdata[i].toString(16).padStart(2, '0').toUpperCase()+" ";}dispstr= "读Ntag卡成功,卡号:" + cardnohex ;				                RWdata.value=datahex;break;case 0x08:dispstr= "读卡失败,未寻到卡!"				                break;case 0x09:dispstr= "读卡失败!两张以上卡片同时在感应区发生冲突!"				                break;case 0x0c:for (i=2;i<=8;i++){cardnohex=cardnohex+getdata[i].toString(16).padStart(2, '0').toUpperCase();}dispstr= "卡密码认证失败,卡号:" + cardnohex +",读取块数据失败!";				                break;case 0x0d:for (i=2;i<=8;i++){cardnohex=cardnohex+getdata[i].toString(16).padStart(2, '0').toUpperCase();}dispstr= "可能要带密码操作,卡号:" + cardnohex +",读取块数据失败!";				                break;default:dispstr= "读卡失败,返回错误代码:"+getdata[1].toString();}label_disp.innerText=dispstr;break;case 7:    //写Ntag卡的回应case 8:    //初始化Ntag卡的回应switch (getdata[1]){case 0x00:for (i=2;i<=8;i++){cardnohex=cardnohex+getdata[i].toString(16).padStart(2, '0').toUpperCase();}				                dispstr= "写Ntag卡成功,卡号:" + cardnohex ;				                break;case 0x08:dispstr= "读卡失败,未寻到卡!"				                break;case 0x09:dispstr= "写卡失败!两张以上卡片同时在感应区发生冲突!"				                break;case 0x0c:for (i=2;i<=8;i++){cardnohex=cardnohex+getdata[i].toString(16).padStart(2, '0').toUpperCase();}dispstr= "卡密码认证失败,卡号:" + cardnohex +",写块数据失败!";				                break;case 0x0e:for (i=2;i<=8;i++){cardnohex=cardnohex+getdata[i].toString(16).padStart(2, '0').toUpperCase();}dispstr= "可能要带密码操作,卡号:" + cardnohex +",写块数据失败!";				                break;default:dispstr= "写卡失败,返回错误代码:"+getdata[1].toString();}label_disp.innerText=dispstr;break;}		        DataPoint=0;        //数据接收指针置0}}		async function listenReceived(){if (reading){console.log("On reading.");return;}reading=true;while (port.readable && reading) {reader = port.readable.getReader();try {updateInputData(value);} catch (e) {alert(e);} finally {reader.releaseLock();}}await port.close(); // 关闭串口port = null;alert("串口已关闭!");}async function OpenSerial(){if (port==null){alert('请先选择要操作的串口号!');return;}else{document.getElementById('butt_closeserial').hidden=false;	var baudSelected = parseInt(document.getElementById("select_btn").value);await port.open({baudRate: baudSelected,					});	listenReceived();	alert('串口打开成功!');							}			}async function CloseSerial(){if ((port == null) || (!port.writable)) {alert("请选择并打开与发卡器相连的串口!");return;}if (reading) {reading = false;reader?.cancel();}	document.getElementById('butt_openserial').hidden=true;document.getElementById('butt_closeserial').hidden=true;		}function selecheckauthkey(){			if (checkauth.checked){				document.getElementById('dispauthkey').hidden=false;document.getElementById('authkey0').hidden=false;}else{document.getElementById('dispauthkey').hidden=true;document.getElementById('authkey0').hidden=true;}			}async function beep(){if ((port == null) || (!port.writable)) {alert("请选择并打开与发卡器相连的串口!");return;}var beepdelay=parseInt(document.getElementById("beepdelay").value);const outputData = new Uint8Array(5);outputData[0]=0x03;     outputData[1]=0x0f;   outputData[2]=beepdelay % 256;outputData[3]=beepdelay / 256;outputData[4]=outputData[1] ^ outputData[2] ^outputData[3];var sendhex="";for(i=0;i<5;i++){sendhex=sendhex+outputData[i].toString(16).padStart(2, '0').toUpperCase()+" ";}			SendData.value=sendhex;ReceiveData.value="";SendCode=1;DataPoint=0;const writer = port.writable.getWriter();await writer.write(outputData);           // 发送数据writer.releaseLock();}async function piccinit_ntag(){if ((port == null) || (!port.writable)) {alert("请选择并打开与发卡器相连的串口!");return;}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,AUTH0myctrlword = myctrlword + 0x01; //更新控制字mypiccdata = mypiccdata + "000000000000000000000000";myctrlword = myctrlword + 0x02; //更新控制字}const outputData = new Uint8Array(31);outputData[0]=0x1d;            //指令数据长度       outputData[1]=0x16;            //功能码outputData[2]=myctrlword;      //控制位for (i=0;i<7;i++){             //7字节本次操作卡UID,7字节全部取0表示可操作任意ntag标签outputData[3+i]=parseInt(mypiccserial.substr(i*2,2),16);}for (i=0;i<4;i++){             //4字节卡片认证密钥outputData[10+i]=parseInt(mypicckey.substr(i*2,2),16);}for (i=0;i<16;i++){            //16字节初化数据 outputData[14+i]=parseInt(mypiccdata.substr(i*2,2),16);}var crc=0;for (i=1;i<30;i++){crc=crc^outputData[i];}outputData[30]=crc;	          //指令信息累加和校验位var sendhex="";for(i=0;i<31;i++){sendhex=sendhex+outputData[i].toString(16).padStart(2, '0').toUpperCase()+" ";}			SendData.value=sendhex;ReceiveData.value="";SendCode=8;DataPoint=0;var label_disp = document.getElementById('label_disp');label_disp.innerText = "";const writer = port.writable.getWriter();await writer.write(outputData);           // 发送数据writer.releaseLock();			}async function readcard_ntag(){if ((port == null) || (!port.writable)) {alert("请选择并打开与发卡器相连的串口!");return;}			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;}else if(myblocksize>12){alert( "每次最多读取12块数据!");ntagpagenumber.focus();ntagpagenumber.select();ntagpagenumber.value="12";return;}const outputData = new Uint8Array(17);outputData[0]=0x0f;            //指令数据长度       outputData[1]=0x1b;            //功能码outputData[2]=myctrlword;      //控制位for (i=0;i<7;i++){             //7字节本次操作卡UID,7字节全部取0表示可操作任意ntag标签outputData[3+i]=parseInt(mypiccserial.substr(i*2,2),16);}for (i=0;i<4;i++){             //4字节卡片认证密钥outputData[10+i]=parseInt(mypicckey.substr(i*2,2),16);}outputData[14]=myblockaddr;    //读卡起始块outputData[15]=myblocksize;    //读卡总块数var crc=0;for (i=1;i<16;i++){crc=crc^outputData[i];}outputData[16]=crc;	          //指令信息累加和校验位var sendhex="";for(i=0;i<17;i++){sendhex=sendhex+outputData[i].toString(16).padStart(2, '0').toUpperCase()+" ";}			SendData.value=sendhex;ReceiveData.value="";RWdata.value="";SendCode=6;DataPoint=0;var label_disp = document.getElementById('label_disp');label_disp.innerText = "";const writer = port.writable.getWriter();await writer.write(outputData);           // 发送数据writer.releaseLock();			}async function writecard_ntag(){if ((port == null) || (!port.writable)) {alert("请选择并打开与发卡器相连的串口!");return;}			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;}else if(myblocksize>11){alert( "每次最多写入11块数据!");ntagpagenumber.focus();ntagpagenumber.select();ntagpagenumber.value="11";return;}var datalen=myblocksize*4;mypiccdata = RWdata.value.trim();            //写卡数据mypiccdata=mypiccdata.replace(/\s/g, "");if (!isHex(mypiccdata)) {alert( "写卡数据输入错误,请输入"+(datalen*2).toString()+"位16进制写卡数据!");RWdata.focus();RWdata.select();return;}else if(mypiccdata.length<datalen*2){if (confirm("写卡数据不足,是否要后面补0写入?")) {      while (mypiccdata.length<datalen*2){mypiccdata=mypiccdata+"0";}}else{return;}	}const outputData = new Uint8Array(datalen+17);outputData[0]=15+datalen;      //指令数据长度       outputData[1]=0x1c;            //功能码outputData[2]=myctrlword;      //控制位for (i=0;i<7;i++){             //7字节本次操作卡UID,7字节全部取0表示可操作任意ntag标签outputData[3+i]=parseInt(mypiccserial.substr(i*2,2),16);}for (i=0;i<4;i++){             //4字节卡片认证密钥outputData[10+i]=parseInt(mypicckey.substr(i*2,2),16);}outputData[14]=myblockaddr;    //写卡起始块outputData[15]=myblocksize;    //写卡总块数for  (i=0;i<datalen;i++){      //写卡数据outputData[16+i]=parseInt(mypiccdata.substr(i*2,2),16);}var crc=0;                     for (i=1;i<16+datalen;i++){crc=crc^outputData[i];}outputData[16+datalen]=crc;	   //指令信息累加和校验位var sendhex="";for(i=0;i<17+datalen;i++){sendhex=sendhex+outputData[i].toString(16).padStart(2, '0').toUpperCase()+" ";}			SendData.value=sendhex;ReceiveData.value="";SendCode=7;DataPoint=0;var label_disp = document.getElementById('label_disp');label_disp.innerText = "";const writer = port.writable.getWriter();await writer.write(outputData);           // 发送数据writer.releaseLock();								}</script><style>th {font-family:楷体;background-color:#F6FAFF;		color:blue;}td {font-family:楷体;background-color:#F6FAFF;		}  </style>    </head><body>
<table width="950" height="428"  align="center"><tr><td width="120" height="50">    <input  name="btnSelect"  type="submit" id="btnSelect" style="width:100%" onclick="SelectSerial()" value="选择串口" /></td><td width="800">波特率:<label for="select_btn"></label><select name="select_btn" id="select_btn"><option>1200</option><option>4800</option><option>9600</option><option>14400</option><option selected="selected">19200</option><option>38400</option><option>43000</option><option>57600</option><option>115200</option><option>128000</option><option>230400</option><option>256000</option><option>460800</option><option>921600</option><option>1382400</option></select>&nbsp;数据位:<select name="select_btn2" id="select_data"><option>8</option><option>7</option><option>6</option><option>5</option></select>&nbsp;停止位:<select name="select_btn3" id="select_stop"><option>1</option><option>1.5</option><option>2</option></select>&nbsp;校验位:<select name="select_btn4" id="select_mark"><option>None  无</option><option>Odd   奇</option><option>Even  偶</option><option>Mask  常1</option><option>Space 常0</option></select>&nbsp;<input  name="butt_openserial"  type="submit" id="butt_openserial" style="width:80px" onclick="OpenSerial()" value="打开串口" /><input  name="butt_closeserial"  type="submit" id="butt_closeserial" style="width:80px" onclick="CloseSerial()" value="关闭串口" /></td></tr><tr><td height="36" ><input name="butt_beep"  type="submit" id="butt_beep" style="width:100%" onclick="beep()" value="驱动发卡器响声" /></td><td>响声延时:<input style="color:blue;text-align:center;" name="beepdelay" type="text" id="beepdelay" value="30" size="5" maxlength="4" onkeyup="this.value=this.value.replace(/\D/g,'')"/>毫秒</td></tr><tr><td height="36">&nbsp;</td><td><label style="color:blue;" name="label_disp" id="label_disp"></label></td></tr><tr><td height="36">&nbsp;</td><td><input type="checkbox" name="checkauth" id="checkauth" onchange="selecheckauthkey()"/>      选择先认证卡片密钥再继续以下的操作<label name="dispauthkey" id="dispauthkey">,16进制卡片认证密钥:</label><input style="color:blue;text-align:center;" name="authkey0" type="text" id="authkey0" value="12345678" size="8" maxlength="8" onkeyup="this.value=this.value.replace(/[^0-9a-fA-F]/g,'')"/></td></tr><tr><td height="69"><input style="width:120px" name="butt_piccinit_ntag" type="submit" id="butt_piccinit_ntag" onclick="piccinit_ntag()" value="初始化Ntag卡" /></td><td><p><label for="rwtext"></label><select style="color:blue;" name="selonoff" id="selonoff"><option>开启卡片密钥保护功能</option><option selected="selected">取消卡片密钥保护功能</option></select>,从:<input style="color:blue;text-align:center;" 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 style="color:blue;text-align:center;" name="newkey" type="text" id="newkey" value="12345678" size="8" maxlength="8" onkeyup="this.value=this.value.replace(/[^0-9a-fA-F]/g,'')"/>,允许密钥认证失败次数:<input style="color:blue;text-align:center;" name="keyerrortimes" type="text" id="keyerrortimes" value="0" size="2" maxlength="2" onkeyup="this.value=this.value.replace(/\D/g,'')"/>,PACK密钥确认码:<input style="color:blue;text-align:center;" name="packcode" type="text" id="packcode" value="1234" size="4" maxlength="4" onkeyup="this.value=this.value.replace(/[^0-9a-fA-F]/g,'')"/></p><p style="color:red;">警告:当密钥认证失败次数取值0表示不限制次数,认证密钥操作失败大于设置值时卡片将会报废!</p></td></tr>  <tr><td height="36"><p><input style="width:120px" name="butt_readcard_ntag" type="submit" id="butt_readcard_ntag" onclick="readcard_ntag()" value="轻松读Ntag卡" /></p><p>&nbsp;</p><p><input style="width:120px" name="butt_writecard_ntag" type="submit" id="butt_writecard_ntag" onclick="writecard_ntag()" value="轻松写Ntag卡" /></p></td><td><p>读写起始页:<input style="color:blue;text-align:center;" name="ntagstartno" type="text" id="ntagstartno" value="4" size="4" maxlength="4" onkeyup="this.value=this.value.replace(/\D/g,'')"/>,读写页数:<input style="color:blue;text-align:center;" 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 style="width:800px;color:red;font-family:楷体;" name="RWdata" id="RWdata" cols="100" rows="4" ></textarea></p></td></tr>    <tr><td height="70" scope="row"><p align="center">发送的数据</p></td><td><textarea style="width:800px;color:blue;" name="SendData" id="SendData" cols="100" rows="4" ></textarea></td></tr><tr><td height="70" scope="row"><p align="center">接收的数据</p></td><td><textarea style="width:800px" name="ReceiveData" id="ReceiveData" cols="100" rows="4" ></textarea></td></tr>
</table></body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/36108.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

不锈钢氩弧焊丝ER316L

说明&#xff1a;TG316L 是超低碳的不锈钢焊丝。熔敷金属耐蚀、耐热、抗裂性能优良。防腐蚀性能良好。 用途:用于石油化工、化肥设备等。也可用于要求焊接后不进行热处理的高Cr钢的焊接。

真实评测:可道云teamOS文件上传功能丝滑到爱不释手

对于每日沉浸在图片与视频海洋中的媒体工作者而言&#xff0c;与海量的多媒体文件打交道几乎成了家常便饭。 文件的上传和存储&#xff0c;对他们而言&#xff0c;不仅仅是工作中的一个环节&#xff0c;更像是将一天的辛勤与付出妥善安置的仪式。无论是突发现场的精彩瞬间&am…

海报在线制作系统源码小程序

轻松设计&#xff0c;创意无限 一款基于ThinkPHPFastAdminUniApp开发的海报在线制作系统&#xff0c; 本系统不包含演示站中的素材模板资源。​ 一、引言&#xff1a;设计新纪元&#xff0c;在线海报制作引领潮流 在数字时代&#xff0c;海报已成为传播信息、展示创意的重要媒…

配音软件哪个好用?推荐5款智能配音软件

随着期末考来袭&#xff0c;校园里的空气似乎都凝固了&#xff0c;每个角落都充满了紧张的气氛。 然而&#xff0c;在这紧张的氛围中&#xff0c;有一群学生却显得格外从容&#xff0c;因为他们掌握了一种秘密武器——配音软件。这些软件就像是他们的个人学习助理&#xff0c;…

git 中有关 old mode 100644、new mode 10075的问题解决小结

问题&#xff1a; 同一个文件被修改后&#xff0c;最后代码没有变&#xff0c;文件变了&#xff0c;导致提交了一个空文件 git diff 提示 filemode 发生改变&#xff08;old mode 100644、new mode 10075&#xff09; 解决办法 &#xff1a; 原来是 filemode 的变化&#xff…

虚拟机字节码执行引擎之运行时栈帧结构

概述 执行引擎是Java虚拟机核心的组成部分之一。“虚拟机”是一个相对于“物理机”的概念,这两种机器都有代码执行能力,其区别是物理机的执行引擎是直接建立在处理器、缓存、指令集和操作系统层面上的,而虚拟机的执行引擎则是由软件自行实现的,因此可以不受物理条件制约地定…

彩虹PLM系统:引领汽车行业的数字化转型

彩虹PLM系统&#xff1a;引领汽车行业的数字化转型 彩虹PLM系统作为汽车行业数字化转型的引领者&#xff0c;凭借其卓越的技术实力和丰富的行业经验&#xff0c;为汽车行业带来了全面的解决方案。以下是彩虹PLM系统如何引领汽车行业数字化转型的详细分析&#xff1a; 一、整合全…

约课健身管理系统小程序源码

健身达人的智能助手 一款基于FastAdminThinkPHPUniapp开发的米扬约课健身管理系统&#xff0c;应用于健身房&#xff0c;健身工作室&#xff0c;运动会所&#xff0c;运动场馆&#xff0c;瑜伽馆&#xff0c;拳馆等泛健身行业的场馆中。米扬约课健身致力于为各种健身场馆打造真…

Verilog刷题笔记49——Fsm1同步复位

题目&#xff1a; 解题&#xff1a; module top_module(clk,reset,in,out);input clk;input reset;input in;output out;parameter A0,B1;reg [1:0]current_state,next_state;always(posedge clk)beginif(reset)current_stateB;elsecurrent_statenext_state;endalways(*)beg…

手机图片怎么上传到电脑记事本 保姆级教程

在这个数字化时代&#xff0c;手机成了我们随身携带的摄影棚。无论是旅途中的美景&#xff0c;还是与朋友欢聚的瞬间&#xff0c;手机总能轻松捕捉。然而&#xff0c;手机存储空间有限&#xff0c;那些珍贵的照片和视频&#xff0c;怎样才能安全又方便地保存下来&#xff0c;供…

PFA量杯:精确、实用、高颜值的量杯选择!

您是否在烹饪、实验室实验或日常使用中需要一个精确、实用且高颜值的量杯&#xff1f;PFA量杯是您最佳的选择&#xff01; PFA量杯采用高品质材料制成&#xff0c;具有良好的耐腐蚀性、耐高温性&#xff0c;使用寿命长。透明度极高的杯身&#xff0c;使您在使用时能够清晰地看…

LLM在软件测试中的革新应用

一、引言 随着人工智能技术的蓬勃发展&#xff0c;大语言模型&#xff08;Large Language Model&#xff0c;简称LLM&#xff09;如GPT系列&#xff0c;在自然语言处理领域取得了显著进展。LLM不仅能够处理复杂的自然语言任务&#xff0c;还在多个领域展现出广泛的应用潜力。在…

深圳网页设计收费情况

深圳是中国最具活力和发展速度最快的城市之一&#xff0c;随着经济的快速发展&#xff0c;各种行业都飞速发展&#xff0c;尤其是互联网行业。网页设计是互联网行业的重要组成部分&#xff0c;深圳的网页设计师数量也是非常庞大的。那么&#xff0c;深圳网页设计师的收费情况是…

MySQL之可扩展性(五)

可扩展性 向外扩展 7.在节点上部署分片 需要确定如何在节点上部署数据分片。以下是一些常用的办法: 1.每个分片使用单一数据库&#xff0c;并且数据库名要相同。典型的应用场景是需要为每个分片都能镜像到原应用的结构。这在部署多个应用实例&#xff0c;并且每个实例对应一…

【Linux学习十八】网站管理:防火墙介绍、静态站点、动态站点、域名

1.Apache Apache官网: www.apache.org 软件包名称: httpd 服务端口:80/tcp(http) 443/tcp(https) 配置文件: /etc/httpd/conf/httpd.conf 子配置文件:/etc/httpd/conf.d/*.conf 查看被占用的端口号 netstat -tuln | grep <端口号> 解哪个程序正在使用端口 80&#xff0…

Jenkins通过Squid代理服务器添加局域网节点机器

✨前言&#xff1a; 当jenkins在公网上的时候&#xff0c;如果要添加局域网内的服务器为节点机器构建的时候&#xff0c;这里就需要通过squid代理服务来实现了。当然你也可以使用其他的方式例如Apache等等&#xff0c;这里主要介绍通过Squid的方式。 &#x1f31f;什么是Squi…

DllImport进阶:参数配置与高级主题探究

深入讨论DllImport属性的作用和配置方法 在基础篇中&#xff0c;我们已经简单介绍了DllImport的一些属性。现在我们将深入探讨这些属性的实际应用。 1. EntryPoint EntryPoint属性用于指定要调用的非托管函数的名称。如果托管代码中的函数名与非托管代码中的函数名不同&#…

计算机组成原理 | CPU子系统(3)MIPS32指令架构

MIPS32架构指令格式 MIPS32架构寻址方式 指令的编码与功能

文本生成sql模型(PipableAI/pip-sql-1.3b)

安装环境 pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 pip install transformers 代码 question "What are the email address, town and county of the customers who are of the least common gender?"sc…

203. 移除链表元素【链表】【C++】

题目描述 题目描述 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,6,3,4,5,6], val 6 输出&#xff1a;[1,2,3,4,5] 示例 2&#x…