Web Serial串口通信实现WEB浏览器读写M1卡

 本示例使用的设备:RS232串口RFID NFC IC卡读写器可二次开发编程发卡器USB转COM-淘宝网 (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串口读写器示例 </title><script>		window.onload = function() {document.getElementById('butt_openserial').hidden=true;document.getElementById('butt_closeserial').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:break;case 2:  //读取M1卡序列号的回应case 3:  //读取M1卡扇区数据的回应case 4:  //写M1卡扇区数据的回应case 5:  //修改M1卡扇区数密钥的回应switch (getdata[0]){case 1:  //返回有效数据长度为1switch (getdata[1]){case 8:dispstr = "未寻到卡!" ; break;case 9:dispstr = "两张以上卡片同时在感应区,发生冲突!" ; 										break;case 10:dispstr = "无法选择激活卡片!" ; break;case 11:dispstr = "密码装载失败,卡片序列号已知!" ; break;default:dispstr = "操作卡失败,返回代码:" + getdata[1].ToString() ; 		break;}var label_disp = document.getElementById('label_disp');label_disp.innerText = dispstr;break;		 case 5:  //返回有效数据长度为5								for(i=2;i<6;i++){cardnohex=cardnohex+getdata[i].toString(16).padStart(2, '0').toUpperCase();}if(SendCode==2){dispstr ="读卡序列号";}else if(SendCode==3){dispstr ="读扇区数据";}else if(SendCode==4){dispstr ="写扇区数据";}else if(SendCode==5){dispstr ="修改扇区密码";}	switch (getdata[1]){case 0:										dispstr=dispstr+"成功!卡号:"+cardnohexbreak;case 1:dispstr = dispstr+",密码认证成功,但读写扇区内容失败!卡号:" + cardnohex;break;	case 2:dispstr = dispstr+",第0块操作成功,但第1、2块操作失败,仅扇区内容前16个字节的数据有效!!卡号:" + cardnohex;break;	case 3:dispstr = dispstr+",第0、1块操作成功,但第2块操作失败,仅扇区内容前32个字节的数据有效!!卡号:" + cardnohex;break;	    case 12:dispstr = dispstr+",密码认证失败,卡号:" + cardnohex;break;default:dispstr = dispstr+",操作卡失败,返回代码:" + getdata[1].ToString() ; 		break;		}var label_disp = document.getElementById('label_disp');label_disp.innerText = dispstr;break;case 53:  //返回有效数据长度为53for(i=2;i<6;i++){cardnohex=cardnohex+getdata[i].toString(16).padStart(2, '0').toUpperCase();}dispstr = "读M1卡扇区数据成功,卡号:" + cardnohex;for(i=6;i<DataPoint-1;i++){datahex=datahex+getdata[i].toString(16).padStart(2, '0').toUpperCase()+" ";}var label_disp = document.getElementById('label_disp');label_disp.innerText = dispstr;RWM1Data.value=datahex;break;case 54:  //旧版本设备返回有效数据长度为54for(i=2;i<6;i++){cardnohex=cardnohex+getdata[i].toString(16).padStart(2, '0').toUpperCase();}dispstr = "读M1卡扇区数据成功,卡号:" + cardnohex;for(i=7;i<DataPoint-1;i++){datahex=datahex+getdata[i].toString(16).padStart(2, '0').toUpperCase()+" ";}var label_disp = document.getElementById('label_disp');label_disp.innerText = dispstr;RWM1Data.value=datahex;break;	}break;}DataPoint=0;}}		async function listenReceived(){if (reading){console.log("On reading.");return;}reading=true;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();}			}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 Request(){if ((port == null) || (!port.writable)) {alert("请选择并打开与发卡器相连的串口!");return;}			const outputData = new Uint8Array(3);outputData[0]=0x01;		//指令长度outputData[1]=0xf0;     //功能码outputData[2]=0xf0;		//校验码	var sendhex="";for(i=0;i<3;i++){sendhex=sendhex+outputData[i].toString(16).padStart(2, '0').toUpperCase()+" ";}			SendData.value=sendhex;ReceiveData.value="";SendCode=2;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 ReadM1Card(){if ((port == null) || (!port.writable)) {alert("请选择并打开与发卡器相连的串口!");return;}			if (selinoutkey.selectedIndex==1){myctrlword = BLOCK0_EN + BLOCK1_EN + BLOCK2_EN + EXTERNKEY;    //外部密钥认证}else {myctrlword = BLOCK0_EN + BLOCK1_EN + BLOCK2_EN;}			   //已装载到发卡器内部密钥认证myareano = selareano.selectedIndex;                       		   //指定为本次读取第8区,十进制authmode = selauthmode.selectedIndex;                              //指定密码模式,十进制,大于0表示用A密码认证,推荐用A密码认证mypiccserial = "00000000";         						           //指定本次操作的卡序列号,十六进制,未知时可指定为8个0mypicckey = authkey0.value.trim();                                 //指定卡片密码,十六进制,FFFFFFFFFFFF为卡片厂家出厂密码if (!isHex(mypicckey) || mypicckey.length!=12) {textarea.value = "认证密钥输入错误,请输入正确的12位16进制认证密钥!";authkey0.focus();authkey0.select();return;}            const outputData = new Uint8Array(16);outputData[0]=0x0e;			//指令长度outputData[1]=0x78;			//功能码outputData[2]=myctrlword;	//控制位		outputData[3]=0x00;			//四字节本次操作卡卡号,全部取0表示可操作任意卡outputData[4]=0x00;outputData[5]=0x00;outputData[6]=0x00;outputData[7]=myareano;		//扇区号outputData[8]=authmode;		//密钥认证方式	for(i=0;i<6;i++){           //6字节密钥outputData[9+i]=parseInt(mypicckey.substr(i*2,2),16);}var crc=0;for (i=1;i<15;i++){crc=crc^outputData[i];}outputData[15]=crc;	var sendhex="";for(i=0;i<16;i++){sendhex=sendhex+outputData[i].toString(16).padStart(2, '0').toUpperCase()+" ";}			SendData.value=sendhex;ReceiveData.value="";RWM1Data.value="";SendCode=3;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 WriteM1Card(){if ((port == null) || (!port.writable)) {alert("请选择并打开与发卡器相连的串口!");return;}			if (selinoutkey.selectedIndex==1){myctrlword = BLOCK0_EN + BLOCK1_EN + BLOCK2_EN + EXTERNKEY;    //外部密钥认证}else {myctrlword = BLOCK0_EN + BLOCK1_EN + BLOCK2_EN;}			   //已装载到发卡器内部密钥认证myareano = selareano.selectedIndex;                       		   //指定为本次读取第8区,十进制authmode = selauthmode.selectedIndex;                              //指定密码模式,十进制,大于0表示用A密码认证,推荐用A密码认证mypiccserial = "00000000";         						           //指定本次操作的卡序列号,十六进制,未知时可指定为8个0mypicckey = authkey0.value.trim();                                 //指定卡片密码,十六进制,FFFFFFFFFFFF为卡片厂家出厂密码if (!isHex(mypicckey) || mypicckey.length!=12) {textarea.value = "认证密钥输入错误,请输入正确的12位16进制认证密钥!";authkey0.focus();authkey0.select();return;}     mypiccdata=RWM1Data.value.trim();mypiccdata=mypiccdata.replace(/\s/g, "");if (isHex(mypiccdata)){if(mypiccdata.length<96){if (confirm("写卡数据不足一扇区48个字节,是否要后面补0写入?")) {      while (mypiccdata.length<96){mypiccdata=mypiccdata+"0";}}else{return;}	}}else{alert("请输入96位16进制写卡数据!");return;}const outputData = new Uint8Array(64);outputData[0]=0x3e;			//指令长度outputData[1]=0x69;			//功能码outputData[2]=myctrlword;	//控制位		outputData[3]=0x00;			//四字节本次操作卡卡号,全部取0表示可操作任意卡outputData[4]=0x00;outputData[5]=0x00;outputData[6]=0x00;outputData[7]=myareano;		//扇区号outputData[8]=authmode;		//密钥认证方式	for(i=0;i<6;i++){           //6字节密钥outputData[9+i]=parseInt(mypicckey.substr(i*2,2),16);}for(i=0;i<48;i++){           //48字节写卡数据outputData[15+i]=parseInt(mypiccdata.substr(i*2,2),16);}var crc=0;for (i=1;i<63;i++){crc=crc^outputData[i];}outputData[63]=crc;	var sendhex="";for(i=0;i<64;i++){sendhex=sendhex+outputData[i].toString(16).padStart(2, '0').toUpperCase()+" ";}			SendData.value=sendhex;ReceiveData.value="";SendCode=4;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 changecardkeyex(){if ((port == null) || (!port.writable)) {alert("请选择并打开与发卡器相连的串口!");return;}			if (selinoutkey.selectedIndex==1){myctrlword = BLOCK0_EN + BLOCK1_EN + BLOCK2_EN + EXTERNKEY;    //外部密钥认证}else {myctrlword = BLOCK0_EN + BLOCK1_EN + BLOCK2_EN;}			   //已装载到发卡器内部密钥认证myareano = selareano.selectedIndex;                       		   //指定为本次读取第8区,十进制authmode = selauthmode.selectedIndex;                              //指定密码模式,十进制,大于0表示用A密码认证,推荐用A密码认证mypiccserial = "00000000";         						           //指定本次操作的卡序列号,十六进制,未知时可指定为8个0mypicckey = authkey0.value.trim();                                 //指定卡片密码,十六进制,FFFFFFFFFFFF为卡片厂家出厂密码if (!isHex(mypicckey) || mypicckey.length!=12) {textarea.value = "认证密钥输入错误,请输入正确的12位16进制认证密钥!";authkey0.focus();authkey0.select();return;}     mypicckeyA = newkeya.value.trim();                             //新A密钥if (!isHex(mypicckeyA) || mypicckeyA.length!=12) {textarea.value = "新A密钥输入错误,请输入正确的12位16进制新A密钥!";newkeya.focus();newkeya.select();return;}			mypiccctr = cardctr.value.trim();                             //新控制位,出厂为FF078069,if (!isHex(mypiccctr) || mypiccctr.length!=8) {textarea.value = "新控制位输入错误,请输入正确的8位16进制控制位!";cardctr.focus();cardctr.select();return;}mypicckeyB = newkeyb.value.trim();                             //新B密钥if (!isHex(mypicckeyB) || mypicckeyB.length!=12) {textarea.value = "新B密钥输入错误,请输入正确的12位16进制新B密钥!";newkeyb.focus();newkeyb.select();return;}mypicckey_new=mypicckeyA+mypiccctr+mypicckeyB;switch (selchangekey.selectedIndex){case 0:mypicckey_new=mypicckey_new+"00";break;case 1:mypicckey_new=mypicckey_new+"02";break;					default:mypicckey_new=mypicckey_new+"03";break;					}						const outputData = new Uint8Array(33);outputData[0]=0x1f;			//指令长度outputData[1]=0xf1;			//功能码outputData[2]=myctrlword;	//控制位		outputData[3]=0x00;			//四字节本次操作卡卡号,全部取0表示可操作任意卡outputData[4]=0x00;outputData[5]=0x00;outputData[6]=0x00;outputData[7]=myareano;		//扇区号outputData[8]=authmode;		//密钥认证方式	for(i=0;i<6;i++){           //6字节密钥outputData[9+i]=parseInt(mypicckey.substr(i*2,2),16);}for(i=0;i<17;i++){           //6字节新A钥+4字节控制位+6字节新B钥+1字节密钥修改类型outputData[15+i]=parseInt(mypicckey_new.substr(i*2,2),16);}var crc=0;for (i=1;i<32;i++){crc=crc^outputData[i];}outputData[32]=crc;	var sendhex="";for(i=0;i<33;i++){sendhex=sendhex+outputData[i].toString(16).padStart(2, '0').toUpperCase()+" ";}			SendData.value=sendhex;ReceiveData.value="";SendCode=5;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="423"  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"><input name="butt_request"  type="submit" id="butt_request" style="width:100%" onclick="Request()" value="仅读取M1卡序列号" /></td><td><label style="color:blue;" name="label_disp" id="label_disp"></label></td></tr><tr><td height="36"><input name="butt_readm1"  type="submit" id="butt_readm1" style="width:100%" onclick="ReadM1Card()" value="读取M1卡扇区数据" /></td><td><p>扇区号:<select style="color:blue;" name="selareano" id="selareano"><option selected="selected">第0扇区</option><option>第1扇区</option><option>第2扇区</option><option>第3扇区</option><option>第4扇区</option><option>第5扇区</option><option>第6扇区</option><option>第7扇区</option><option>第8扇区</option><option>第9扇区</option><option>第10扇区</option><option>第11扇区</option><option>第12扇区</option><option>第13扇区</option><option>第14扇区</option><option>第15扇区</option>        </select><label for="changeauthkey"></label><select style="color:blue;" name="selinoutkey" id="selinoutkey"><option>内部密钥认证</option><option selected="selected">外部密钥认证</option></select><label for="newkey"></label><select style="color:blue;" name="selauthmode" id="selauthmode"><option>B密钥认证</option><option selected="selected">A密钥认证</option>        </select>,认证密钥:<label for="authkey0"></label><input style="color:blue;text-align:center;" name="authkey0" type="text" id="authkey0" value="FFFFFFFFFFFF" size="12" maxlength="12" onkeyup="this.value=this.value.replace(/[^0-9a-fA-F]/g,'')"/></p>    </td></tr><tr><td height="69"><input name="butt_writem1"  type="submit" id="butt_writem1" style="width:100%" onclick="WriteM1Card()" value="写数据到M1卡扇区" /></td><td><textarea style="width:800px;color:red;" name="RWM1Data" id="RWM1Data" cols="100" rows="4" ></textarea></td></tr>  <tr><td height="36"><input style="width:100%" name="butt_changecardkeyex" type="submit" id="butt_changecardkeyex" onclick="changecardkeyex()" value="修改M1卡扇区密钥" /></td><td><select style="color:blue;" name="selchangekey" id="selchangekey"><option>只修改A密钥</option><option>只修改AB密钥</option><option selected="selected">修改AB密钥及控制位</option></select>,新A密钥<input style="color:red;text-align:center;" name="newkeya" type="text" id="newkeya" value="FFFFFFFFFFFF" size="12" maxlength="12" onkeyup="this.value=this.value.replace(/[^0-9a-fA-F]/g,'')"/>,控制位<input style="color:red;text-align:center;" name="cardctr" type="text" id="cardctr" value="FF078069" size="8" maxlength="8" onkeyup="this.value=this.value.replace(/[^0-9a-fA-F]/g,'')"/>,B密钥<input style="color:red;text-align:center;" name="newkeyb" type="text" id="newkeyb" value="FFFFFFFFFFFF" size="12" maxlength="12" onkeyup="this.value=this.value.replace(/[^0-9a-fA-F]/g,'')"/></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>

源码下载:WebSerialapi浏览器串口通讯读写NFC标签资源-CSDN文库

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

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

相关文章

优思学院|工厂的部门架构管理与精益生产

工厂内有不同部门&#xff0c;各部门之间必须协调合作才能发挥整体功能。工厂最主要的部分是制造产品的现场&#xff0c;这里安装了生产工具&#xff0c;还有操作员进行加工或生产制造。 制造时使用的材料或零组件&#xff0c;需要对外采购。对于加工组装型的工厂&#xff0c;…

基于Boost和平均电流控制方法的APFC电路设计

通过学习无线充电相关知识&#xff0c;为更快熟悉APFC工作原理&#xff0c;通过实验得以掌握 技术要求&#xff1a; 1&#xff09;输入电压&#xff1a;AC 85V&#xff5e;265V&#xff1b; 2&#xff09;输出电压&#xff1a;400V1%&#xff1b; 3&#xff09;输出额定电流…

音视频开发30 FFmpeg 视频编码- 流程以及重要API,H264编码原理说明,该章节使用h264编码说明

一.H264编码原理 1 视频为什么需要进行编码压缩 ◼ 一张为 720x480 的图像&#xff0c;用 YUV420P 的格式来表示&#xff0c;其大小为&#xff1a; 720*480*1.5 约等于 0.5MB 。 ◼ 如果是 25 帧&#xff0c; 10 分钟的数据量 0.5M*10*60*25 7500MB -> 7GB 多 ◼ …

自学网络安全的三个必经阶段(含路线图)

一、为什么选择网络安全&#xff1f; 这几年随着我国《国家网络空间安全战略》《网络安全法》《网络安全等级保护2.0》等一系列政策/法规/标准的持续落地&#xff0c;网络安全行业地位、薪资随之水涨船高。 未来3-5年&#xff0c;是安全行业的黄金发展期&#xff0c;提前踏入…

blender 快捷键 常见问题

一、快捷键 平移视图&#xff1a;Shift 鼠标中键旋转视图&#xff1a;鼠标中键缩放视图&#xff1a;鼠标滚动框选放大模型&#xff1a;Shift B线框预览和材质预览切换&#xff1a;Shift Z 二、常见问题 问题&#xff1a;导入模型成功&#xff0c;但是场景中看不到。 解…

电路与数字逻辑期末复习重点整理!!

1.带无关项的卡诺图 2.置数法设计N进制电路 计数器&#xff1a;具有记忆输入脉冲个数功能的电路称为计数器。 按照各个触发器状态更新情况的不同可分为&#xff1a; 同步计数器&#xff1a;各触发器受同一时钟脉冲─输入计数脉冲控制&#xff0c;同步更新状态。异步计数器&a…

阿里云centos 7.9 使用宝塔面板部署.netcore 6.0

前言&#xff1a; 我有一个netcore6.0的系统接口和手机端程序的站点程序之前是部署在一台windows测试服务器的IIS站点中&#xff0c; 服务器最近压力太大扛不住了&#xff0c;买了一台centos7.9的阿里云服务器准备进行迁移。具体操作日记如下。 一、安装宝塔面板 这一步涉及…

堡垒机软件详细定义以及部分厂商汇总

随着大家对网络安全的重视&#xff0c;越来越多的企业开始采购堡垒机。堡垒机可以分为硬件堡垒机、软件堡垒机、软硬一体机。今天我们就来聊聊堡垒机软件详细定义以及部分厂商汇总。 堡垒机软件详细定义 堡垒机软件&#xff0c;又称为运维安全审计系统&#xff0c;其主要功能在…

顺序表--数据结构第一关

顺序表 数据结构概念 定义&#xff1a;数据结构是计算机存储、组织数据的⽅式 根据学过C语言的基础上&#xff0c;数组是最简单的数据结构 顺序表的底层就是数组 为什么呢&#xff1f; 例子如下&#xff1a; int arr[100]{1,2,3,4,5}; //修改某一个数据&#xff1a;arr[…

【Docker】docker 替换宿主与容器的映射端口和文件路径

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 docker 替换宿主与容器的映射端口和文件夹 1. 正文 1.1 关闭docker 服务 systemctl stop docker1.2 找到容器的配置文件 cd /var/lib/docker/contain…

游戏爱好者将《超级马里奥64》移植到GBA掌机

GBA虽然在当年拥有多款马里奥系列游戏&#xff0c;不过你一定没有想到&#xff0c;N64的《超级马里奥64》也能被移植到这个游戏掌机。近日&#xff0c;一位名为Joshua Barretto的开发者就完成了这一挑战。 大家都知道&#xff0c;《超级马里奥64》于1996年登陆任天堂64主机&am…

入职必备-mac下载安装maven

1、Maven 下载 1.1、官网下载安装包 官网下载链接 历史版本下载&#xff1a; Index of /dist/maven/maven-3/3.8.8/binaries 注意 .bash_profile 文件中的符号可能会影响配置 1.2、解压文件 2、Maven 环境配置 2.1、Java JDK 依赖 配置 maven 环境变量需要先配置好 JDK …

第一视角:获取VC账号,是成为亚马逊供应商的全面准备与必要条件

在当今全球化、数字化的商业环境中&#xff0c;亚马逊作为全球最大的电子商务平台&#xff0c;为众多企业提供了无限的商业机会。然而&#xff0c;想要成功在亚马逊上立足&#xff0c;成为其优质供应商&#xff0c;并非易事。其中&#xff0c;VC(Vendor Central)账号&#xff0…

低空经济再获新动能!沃飞长空完成新一轮数亿元融资

当下&#xff0c;作为中国"新质生产力"代表的低空经济正在成为新的发展“风口”&#xff0c;全国各地开足马力加速入场。 低空经济有多“火”&#xff1f;政策方面&#xff0c;据不完全统计&#xff0c;已有26个省份的政府工作报告对发展低空经济作出部署&#xff1…

如何做好新闻软文宣发媒体资源筛选?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 媒体宣传加速季&#xff0c;100万补贴享不停&#xff0c;一手媒体资源&#xff0c;全国100城线下落地执行。详情请联系胡老师。 新闻软文宣发是指企业通过创造或利用新闻事件&#xff0c…

使用k8s变更线上版本号

第一步&#xff0c;在镜像仓库中找到历史版本号 第二步&#xff0c;在rancher中在工作负载里 第三步&#xff0c;在rancher找到这个版本号&#xff0c;可以更改之前的版本号 这样就可以很方便的退回到之前的版本了

Django安装与启动

1、Django是什么&#xff1f; 基于python的Web开发框架&#xff0c;支持用户快速开发安全、可维护的网站 2、怎么安装&#xff1f; pip install Django4.2 3、如何启动&#xff1f; 不写ip和端口时候&#xff0c;默认启动http://127.0.0.1:8000/ python .\manage.py runse…

AI时代的量化金融:ChatGPT在交易中的应用与前景

文章目录 &#x1f4d1;前言一、智能量化&#xff1a;开启金融新世界二、作者简介三、本书特色四、适读人群 在数字化、智能化的时代浪潮中&#xff0c;金融领域正经历着一场前所未有的变革。传统的金融分析方法逐渐被高效、精准的量化金融与算法交易所替代&#xff0c;而人工智…

【知识】详细介绍 CUDA Samples 示例工程

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 内容较多&#xff0c;可通过 左侧或右侧 的 目录 进行跳转。 CUDA 是“Compute Unified Device Architecture (计算统一设备架构)”的首字母缩写。CUDA…

应用案例 | Panorama SCADA:开创性的铁路电气控制系统

案例概况 客户&#xff1a;英国铁路网运营商Network Rail 合作伙伴&#xff1a;Telent Technology Services Ltd 应用&#xff1a;实现对铁路牵引电网的高效管理与精准控制 应用产品&#xff1a;宏集Panorama E2 SCADA系统 一、应用背景 英国铁路网运营商Network Rail计划…