HJ212协议C#代码解析实现

HJ212协议C#代码解析实现

HJ212协议是环保中一个非常重要的标准协议(字符串协议),之前写了两篇C++ HJ212协议解析的相关博文:

  • 环保 HJ212协议解析
  • 基于Qt5.14.2的HJ212 TCP服务端接收解析入库程序
    最近在学习C#,所以打算基于C#重新实现一遍,算是熟悉一下C#的基本语法。

HJ212协议简介

由于是做环保相关的,有时需要对212协议进行拆包和解包。HJ212协议是一种字符串协议,数据传输通讯包主要由包头、数据段长度、数据段、CRC校验、包尾组成,其中“数据段”内容包括请求编码、系统编码、命令编码、密码、设备唯一标识、总包数、包号、指令参数。请求编码为请求的时间戳,系统编码ST统一规定为22,命令编码CN为该数据包的时间类型,访问密码、设备唯一标识在对接时由平台提供,指令参数为数据内容。通讯协议的数据结构如图4所示。
通讯协议的数据结构
图4 通讯协议的数据结构

6.1.1通讯包结构组成

名称类型长度描述
包头字符2固定为##
数据段长度十进制整数4数据段的ASCII字符数。例如数据段的字符数为128,则写为“0128”
数据段字符0<=n<=9999变长的数据
CRC校验十六进制4数据段的校验结果,例如C901,如果CRC错,即执行超时
包尾字符2回车换行(\r\n)

《污染物在线监控(监测)系统数据传输标准》简称《HJ212-2017》标准PDF文档可以从中华人民共和国生态环境部的官网下载,具体地址为:HJ212-2017》标准PDF文档
如下图所示:
HJ212-2017标准下载
目前HJ212标准协议已经发布了两个版本,一个是HJ/T 212-2005,另一个是 HJ 212-2017,最新的HJ 212-2017下载地址为:污染物在线监控(监测)系统数据传输标准(HJ 212-2017代替HJ/T 212-2005)

## 基于C#的HJ212解析类

首先创建一个基于C# .Net的库项目,名称为:HJ212ParseLibrary,相关类实现代码如下:

(1)、通用工具类 CommonUtils

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace HJ212ParseLibrary
{/// <summary>/// 通用工具类/// </summary>public class CommonUtils{/// <summary>/// 切分数据/// </summary>/// <param name="cp"></param>/// <returns></returns>public static List<Dictionary<string, string>>  SplitKV(string cp){List<Dictionary<string, string>> resultList = new List<Dictionary<string, string>>();var arr1 = cp.Split(';');foreach (var i in arr1){Dictionary<string, string> item = new Dictionary<string, string>();var arr2 = i.Split(',');foreach(var j in arr2){var arrKv = j.Split('=');if (arrKv.Length == 2){item.Add(arrKv[0], arrKv[1]);   }}resultList.Add(item);}return resultList;}/// <summary>/// 组合数据/// </summary>/// <param name=""></param>/// <returns></returns>public static string JoinKV(List<Dictionary<string, string>> myList){List<string> item = new List<string>();foreach (var i in myList){List<string> arrKv = new List<string>();foreach (var j in i){arrKv.Add(j.Key + "=" + j.Value);}item.Add(Join(arrKv, ','));}return Join(item, ';');}/// <summary>/// 数据组合字符串/// </summary>/// <param name="arrKv">字符串列表</param>/// <param name="sep">分隔符</param>/// <returns></returns>/// <exception cref="NotImplementedException"></exception>private static string Join(List<string> arrKv, char sep = ' '){string result = "";bool isFirst = true;foreach (var item in arrKv){if (isFirst){result = item;isFirst = false;continue;}result += sep + item;}return result;}/// <summary>/// 将字符串数组按照sep分隔符分割之后,生成新的字符串/// </summary>/// <param name="arrKv">字符串数组</param>/// <param name="sep">分隔符</param>/// <returns></returns>private static string Join(string[] arrKv, char sep = ' '){string result = "";bool isFirst = true;foreach (var item in arrKv){if (isFirst){result = item;isFirst = false;continue;}result += sep + item;}return result;}/// <summary>/// 计算计算字节数组的CRC-16校验码/// </summary>/// <param name="byteArr">字节数组</param>/// <returns>CRC-16校验码</returns>public static uint GetCrc16(byte[] byteArr){uint crc_reg, check;int i, j;crc_reg = 0xFFFF;for (i = 0; i < byteArr.Length; i++){crc_reg = (crc_reg >> 8) ^ byteArr[i];for (j = 0; j < 8; j++){check = crc_reg & 0x0001;crc_reg >>= 1;if (check == 0x0001){crc_reg ^= 0xA001;}}}return crc_reg;}/// <summary>/// 将对应位置置1,n从1开始/// </summary>/// <param name="x"></param>/// <param name="n"></param>public static void SetBit(int x, int n){x |= 1 << (n - 1);}/// <summary>/// 将对应位置置0,n从1开始/// </summary>/// <param name="x"></param>/// <param name="n"></param>public static void CtrlBit(int x, int n){x &= ~(1 << (n - 1));}public static int GetBit(int x, int n){return x & (1 << (n - 1));}}
}

(2)、HJ212协议 CP数据部分 HJ212DataCP

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace HJ212ParseLibrary
{/// <summary>/// HJ212协议 CP数据部分/// </summary>public class HJ212DataCP{public HJ212DataCP(){}public HJ212DataCP(string s){List<Dictionary<string, string>> arr = CommonUtils.SplitKV(s);foreach (var i in arr){int kvlen = i.Count;string key = "";foreach (var j in i){// 对指定监测因子的项,统一使用因子代表if (j.Key == "PolId"){key = j.Value;this.KVDict[key] = new Dictionary<string, string>();continue;}string name, field;// 查询是否包含标准协议中的设备状态var f1 = j.Key.IndexOf("SB");var f2 = j.Key.IndexOf("-");if (f2 != -1 && f1 != 0){// a20004-Rtd   name-fieldname = j.Key.Substring(0, f2);field = j.Key.Substring(f2 + 1);// i11001-Info   fieldif (field == "Info"){field = name;}else{key = name;}}else{if (j.Key == "DataTime"){this.DataTime = j.Value;}name = j.Key;key = name;field = "value";}if (this.KVDict.ContainsKey(key)){// 如果存在key,则追加this.KVDict[key].Add(field, j.Value);} else{// 如果不存在该key,则创建一个字典对象,并添加到KVDict中Dictionary<string, string> dict = new Dictionary<string, string>();dict.Add(field, j.Value);this.KVDict.Add(key, dict);}}}}public void Clear(){this.KVDict.Clear();}public Dictionary<string, Dictionary<string, string>> KVDict = new Dictionary<string, Dictionary<string, string>>();   // 监测因子数据字典string DataTime;}
}

(3)、HJ212协议 数据区 HJ212Data

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace HJ212ParseLibrary
{/// <summary>/// HJ212协议 数据区/// 请求编码QN + 系统编码ST + 命令编码CN + 密码PW + 设备唯一标识MN + 标志位Flag + 总包数PNUM + 包号PNO + 指令参数CP/// 其中,指令CP字符数范围为:[0,9899],CP=&&数据区&&/// </summary>public class HJ212Data{public string QN;		// 请求编码 20字符	QN=YYYYMMDDHHmmssZZZpublic string ST;		// 系统编码 5字符		ST=21public string CN;		// 命令编码 7字符		CN=2011public string PW;		// 访问密码 9字符		PW=123456public string MN;		// 设备标识 27字符	MN=[0-9A-F]public string Flag;	    // 标志位   8整数		Flag=7	bit:000001(协议版本)0(是否有包号)0(是否需应答)public string PNUM;	    // 总包数   9字符		PNUM=0000	[不分包则没有本字段]public string PNO;		// 包号     8字符	PNO=0000	[不分包则没有本字段]public string CP;		// 指令参数	<=9899字符	CP=&&数据区&&public HJ212DataCP CPs;private bool bValid = false;// 设置Flag,bit从1开始public void SetFlag(int bit, bool enable){int flag = 4;flag = Int32.Parse(Flag);if (enable){CommonUtils.SetBit(flag, bit);} else{CommonUtils.CtrlBit(flag, bit);}this.Flag = flag.ToString();}// 获取Flag,bit从1开始public int GetFlag(int bit){int flag = 4;if (Int32.TryParse(Flag, out flag)){return CommonUtils.GetBit(flag, bit);}return CommonUtils.GetBit(flag, bit);}// 有效性public bool IsValid(){return bValid;}// 长度public int Size(){return QN.Length + ST.Length + CN.Length + PW.Length + MN.Length +Flag.Length + PNUM.Length + PNO.Length + CP.Length;}// 构造函数public HJ212Data(){}public HJ212Data(string s){CopyStr(s);}public void CopyStr(string s){// 查找数据段int d1 = s.IndexOf("CP=&&");        // 数据段开始位置int d2 = s.IndexOf("&&", d1 + 5);   // 数据段结束位置String tmpStr = "";if (d1 != -1 && d2 != -1){CP = s.Substring(d1 + 5, d2 - d1 - 5);CPs = new HJ212DataCP(CP);tmpStr = s.Substring(0, d1) + s.Substring(d2 + 2);}else{tmpStr = s;}Dictionary<string, string> strDict = new Dictionary<string, string>();var arr1 = tmpStr.Split(';');foreach (var i in arr1){var arr2 = i.Split('=');if (arr2.Length == 2){strDict.Add(arr2[0], arr2[1]);}}if (strDict.ContainsKey("QN")){QN = strDict["QN"];}if (strDict.ContainsKey("ST")){ST = strDict["ST"];}if (strDict.ContainsKey("CN")){CN = strDict["CN"];}if (strDict.ContainsKey("PW")){PW = strDict["PW"];}if (strDict.ContainsKey("MN")){MN = strDict["MN"];}if (strDict.ContainsKey("Flag")){Flag = strDict["Flag"];}if (strDict.ContainsKey("PNUM")){PNUM = strDict["PNUM"];}if (strDict.ContainsKey("PNO")){PNO = strDict["PNO"];}bValid = true;}// 获取数据项public List<Dictionary<string, string>> Cp2Object(){return CommonUtils.SplitKV(CP);}// 字符串输出public override string ToString(){string str = "";if (!string.IsNullOrEmpty(QN)){str += ("QN=" + QN + ";");}if (!string.IsNullOrEmpty(ST)){str += ("ST=" + ST + ";");}if (!string.IsNullOrEmpty(CN)){str += ("CN=" + CN + ";");}if (!string.IsNullOrEmpty(PW)){str += ("PW=" + PW + ";");}if (!string.IsNullOrEmpty(MN)){str += ("MN=" + MN + ";");}if (!string.IsNullOrEmpty(Flag)){str += ("Flag=" + Flag + ";");}if (!string.IsNullOrEmpty(PNUM)){str += ("PNUM=" + PNUM + ";");}if (!string.IsNullOrEmpty(PNO)){str += ("PNO=" + PNO + ";");}str += ("CP=&&" + CP + "&&");return str;}}
}

(4)、HJ212协议实体类 HJ212

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using System.Threading.Tasks;namespace HJ212ParseLibrary
{/// <summary>/// HJ212协议 整包=包头+数据段长度+数据段+CRC校验+包尾组成/// ##0637ST=22;CN=2011;PW=123456;MN=LB4200001;CP=&&DataTime=20210107143500;a05002-Rtd=0,a05002-Flag=N;a21005-Rtd=0.825,a21005-Flag=N;a34006-Rtd=874,a34006-Flag=N;a24088-Rtd=0,a24088-Flag=N;a21003-Rtd=5.656,a21003-Flag=N;a21004-Rtd=9.253,a21004-Flag=N;a21002-Rtd=17.894,a21002-Flag=N;a05024-Rtd=5.803,a05024-Flag=N;a34007-Rtd=2679,a34007-Flag=N;a34002-Rtd=123.97,a34002-Flag=N;a34004-Rtd=24.82,a34004-Flag=N;a01006-Rtd=1032.3,a01006-Flag=N;a01002-Rtd=20.9,a01002-Flag=N;a21026-Rtd=0.795,a21026-Flag=N;a01007-Rtd=3.3,a01007-Flag=N;a34049-Rtd=3553,a34049-Flag=N;a01001-Rtd=-0.6,a01001-Flag=N;a99999-Rtd=0,a99999-Flag=N;a01008-Rtd=349,a01008-Flag=N&&3300/// </summary>public class HJ212{public string header = "##";        // 包头 2字符public string dataLen = "0000";     // 数据段长度    4整数,如长度128,写为"0128"HJ212Data data;                     // 数据段  0<=n<=9999public string crc = "0000";         // CRC校验码  4hexpublic string tailer = "\r\n";      // 包尾 2字符public string full;                 // 全数据,整包/// 输出public override string ToString(){string dataStr = data.ToString();uint crc16 = CommonUtils.GetCrc16(Encoding.UTF8.GetBytes(dataStr));return string.Format("{0}{1:D4}{2}{3:X4}{4}", header, dataStr.Length, dataStr, crc16, tailer);  // D4标示4位10进制数字,X4表示4位16进制数}// 有效性public bool IsValid(){return bValid;}// 有效性public bool IsDataValid(){return this.data.CN == "2011" || this.data.CN == "2051" || this.data.CN == "2061"|| this.data.CN == "2031" || this.data.CN == "2041" || this.data.CN == "3020";}// 长度public int Size(){return header.Length + dataLen.Length + data.Size() + crc.Length + tailer.Length;}// 清空数据区public void ClearCp(){this.data.CP = "";this.data.CPs.Clear();}// 设置是否需要应答public void SetNeedReply(bool need){data.SetFlag(1, need);}// 设置是否有包号public void SetNeedSubPack(bool need){data.SetFlag(2, need);if (!need){data.PNUM = "";data.PNO = "";}}// 是否需应答public int IsNeedReply(){return data.GetFlag(1);}// 是否有包号public int IsNeedSubPack(){return data.GetFlag(2);}// 数据区。字段与其值用‘=’连接;// 在数据区中,同一项目的不同分类值间用‘,’来分隔,不同项目之间 用‘;’来分隔。public void Combine(){this.dataLen = string.Format("{0:D4", this.data.Size());string dataStr = this.data.ToString();uint jisuanCrc = CommonUtils.GetCrc16(Encoding.UTF8.GetBytes(dataStr));this.crc = string.Format("{0:D4", jisuanCrc);this.bValid = true;}public HJ212(string str){this.full = str;int totalSize = str.Length;dataLen = str.Substring(header.Length, dataLen.Length);int dLen = Int32.Parse(dataLen);if ((10 + dLen) > totalSize) {return;}string dataStr = str.Substring(header.Length + dataLen.Length, dLen);data = new HJ212Data(dataStr);crc = str.Substring(header.Length + dataLen.Length + dLen, crc.Length);//uint jisuanCrc16 = CommonUtils.GetCrc16(dataStr.ToCharArray());uint jisuanCrc16 = CommonUtils.GetCrc16(Encoding.UTF8.GetBytes(dataStr));int srcCrc16 = Int32.Parse(crc, System.Globalization.NumberStyles.HexNumber);if (srcCrc16 != jisuanCrc16) {return;}bValid = true;}public HJ212(HJ212 r){this.header = r.header;this.dataLen = r.dataLen;//this.data = new HJ212Data(r.data.ToString());this.data = r.data;this.crc = r.crc;this.tailer = r.tailer;this.full = r.full;this.bValid = r.bValid;}public HJ212(string st, string cn, string mn, string pw, string cp, bool needReply){this.data.QN = DateTime.Now.ToString("yyyyMMDDHHMMss000");this.data.ST = st;this.data.CN = cn;this.data.PW = pw;this.data.CP = cp;this.SetNeedReply(needReply);this.Combine();}// 获取响应报文public HJ212 GetDataResponse(string cn){HJ212 outHJ212 = new HJ212(this);outHJ212.data.ST = "91";outHJ212.data.CN = cn;outHJ212.ClearCp();outHJ212.Combine();return outHJ212;}/// <summary>/// 解析字符串,获取HJ212协议数据列表/// </summary>/// <param name="buffer">输入字符串</param>/// <returns>返回解析后的HJ212协议列表</returns>public static List<HJ212> Parse(string buffer){List<HJ212> hj212List = new List<HJ212>();int bufferSize = buffer.Length;string strTemp = "";for (int i = 0; i < bufferSize; i++){if ( i < bufferSize - 1 && buffer[i] == '#' && buffer[i + 1] == '#'){if (strTemp.Length > 0){hj212List.Add(new HJ212(strTemp));strTemp = "";}}strTemp += buffer[i];// 遍历到HJ212协议末尾,末尾以\r\n结束if (i > 0 && buffer[i - 1] == '\r' && buffer[i] == '\n'){if (strTemp.Length > 0){hj212List.Add(new HJ212(strTemp));strTemp = "";}}}if (strTemp.Length > 0){hj212List.Add(new HJ212(strTemp));strTemp = "";}return hj212List;}private bool bValid = false;}
}

测试程序

新建一个基于C# .Net的控制台程序ConsoleHJ212App,然后输入如下测试代码:

using HJ212ParseLibrary;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace ConsoleHJ212App
{public class Program{static void Main(string[] args){string buffer = "##0637ST=22;CN=2011;PW=123456;MN=LB4200001;CP=&&DataTime=20210107143500;a05002-Rtd=0,a05002-Flag=N;a21005-Rtd=0.825,a21005-Flag=N;a34006-Rtd=874,a34006-Flag=N;a24088-Rtd=0,a24088-Flag=N;a21003-Rtd=5.656,a21003-Flag=N;a21004-Rtd=9.253,a21004-Flag=N;a21002-Rtd=17.894,a21002-Flag=N;a05024-Rtd=5.803,a05024-Flag=N;a34007-Rtd=2679,a34007-Flag=N;a34002-Rtd=123.97,a34002-Flag=N;a34004-Rtd=24.82,a34004-Flag=N;a01006-Rtd=1032.3,a01006-Flag=N;a01002-Rtd=20.9,a01002-Flag=N;a21026-Rtd=0.795,a21026-Flag=N;a01007-Rtd=3.3,a01007-Flag=N;a34049-Rtd=3553,a34049-Flag=N;a01001-Rtd=-0.6,a01001-Flag=N;a99999-Rtd=0,a99999-Flag=N;a01008-Rtd=349,a01008-Flag=N&&3300\r\n##0404ST=22;CN=2011;PW=123456;MN=LB4200001;CP=&&DataTime=20210107152600;a05002-Rtd=1.755,a05002-Flag=N;a21005-Rtd=0.699,a21005-Flag=N;a34006-Rtd=845,a34006-Flag=N;a24088-Rtd=4.945,a24088-Flag=N;a21003-Rtd=3.877,a21003-Flag=N;a21002-Rtd=14.502,a21002-Flag=N;a05024-Rtd=10.389,a05024-Flag=N;a34007-Rtd=2859,a34007-Flag=N;a21026-Rtd=1.525,a21026-Flag=N;a34049-Rtd=3704,a34049-Flag=N;a99999-Rtd=6.7,a99999-Flag=N&&9C01\r\n";List<HJ212> hj212List = HJ212.Parse(buffer);foreach (HJ212 item in hj212List){Console.WriteLine(item.ToString());}}}
}

并引用HJ212ParseLibrary库项目,在VS2022中运行结果如下图所示:
调试运行结果1

运行结果如下:
解析HJ212协议测试实例
可以看到,我们输入的数据和解析到的数据是一致的,有2个协议数据报文。

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

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

相关文章

接口幂等性问题和常见解决方案

接口幂等性问题和常见解决方案 1.什么是接口幂等性问题1.1 会产生接口幂等性的问题1.2 解决思路 2.接口幂等性的解决方案2.1 唯一索引解决方案2.2 乐观锁解决方案2.3 分布式锁解决方案2.4 Token解决方案(最优方案) 3 Token解决方案落地3.1 token获取、token校验3.2 自定义注解,…

小蓝的漆房——算法思路

题目链接&#xff1a;1.小蓝的漆房 - 蓝桥云课 (lanqiao.cn) 本题只要是通过枚举的方法&#xff0c;算出涂成每一种颜色所需的天数&#xff0c;最后在所有天数中找出最小值&#xff08;由题可知&#xff0c;最多只有60种颜色&#xff0c;所以可以尝试算出每种颜色所需的时间&am…

LeetCode刷题小记 八、【回溯算法】

1.回溯算法 文章目录 1.回溯算法写在前面1.1回溯算法基本知识1.2组合问题1.3组合问题的剪枝操作1.4组合总和III1.5电话号码的字母组合1.6组合总和1.7组合总和II1.8分割回文串1.9复原IP地址1.10子集问题1.11子集II1.12非递减子序列1.13全排列1.14全排列II1.15N皇后1.16解数独 写…

react中hooks使用限制

只能在最顶层使用Hook 不要在循环、条件中调用hook&#xff0c;确保总是在React函数最顶层使用它们 只能React函数中调用Hook 不要在普通的js函数中调用 在React的函数组件中调用Hook 在自定义hook中调用其他hook 原因&#xff1a; 我们每次的状态值或者依赖项存在哪里&…

springCloudeAlibaba的使用

父pom文件&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.o…

数据库中逻辑运算符的介绍以及优先级表

简介&#xff1a;逻辑运算符主要判断表达式的真假&#xff0c;返回值为1&#xff0c;0&#xff0c;null 其中包含&#xff1a; 逻辑非&#xff1a;not或&#xff01; 逻辑与&#xff1a;and或&& 逻辑或&#xff1a;or或|| 逻辑异或&#xff1a;XOR 1.逻辑非运算 规则…

mac打开exe文件的三大方法 mac怎么运行exe文件 mac打开exe游戏 macbookpro打开exe

exe文件是Windows系统的可执行文件&#xff0c;虽然Mac系统上无法直接打开exe文件&#xff0c;但是你可以在Mac电脑上安装双系统或者虚拟机来实现mac电脑上运行exe文件。除了这两种方法之外&#xff0c;你还可以在Mac电脑上使用类虚拟机软件打开exe文件&#xff0c;这三种方法各…

双指针 | 移动零 | 复写零

1.移动零 题目描述&#xff1a; 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 示例&#xff1a; 输入: nums [0,1,0,3,12] 输出: [1,3,12,0,0]解题思路&#xff1a; right指针一直往后移动&#xff0c;当…

欧洲跨境物流仓库视频监控系统开发的解决方案

中国联通针对仓储物流行业的数字化需求&#xff0c;提供全面的解决方案&#xff0c;特别是在海外仓储领域&#xff0c;我们深谙企业面临的挑战&#xff0c;如预算限制、仓储空间需求以及城郊网络覆盖不足等问题。我们利用自身强大的网络资源和技术实力&#xff0c;为出海仓储企…

redis学习-Hash类型相关命令及特殊情况分析

目录 1. hset KEY key1 value1 key2 value2 ... 2. hget KEY key 3. hgetall KEY 4. hmget KEY key1 key2 ... 5. hkeys KEY 6. hvals KEY 7. hdel KEY key1 key2 ... 8. hlen KEY 9. hexists KEY key 10. hincrby KEY key num 11. hsetnx KEY key value Hash的内部…

实时数仓项目《一》-实时数仓架构

目录 1. 实时数仓与离线数仓 2. 实时数仓需求 3. 架构图 3.1 行为日志处理&#xff1a; 3.2 业务库表处理&#xff1a; 4. 面试题&#xff1a; &#x1f9c0;你们的实时数仓有分层吗&#xff1f; &#x1f9c0;那你们的业务数据呢&#xff1f; &#x1f9c0;那你们的O…

字符分类函数(iscntrl、i是space.....)---c语言

目录 一、定义二、字符分类函数2.1 -iscntrl&#xff08;&#xff09;2.1.1定义2.1.2使用举例 2.2 -isspace&#xff08;&#xff09;2.2.1描述2.2.2使用举例 2.3-isdigit()2.3.1描述2.3.2使用举例 2.4-isxdigit()2.4.1描述 2.5-islower()2.5.1描述2.5.2使用举例 2.6-isupper()…

THM学习笔记—Simple CTF

nmap扫描&#xff0c;发现2222端口很奇怪啊&#xff0c;重新换一种方式扫描2222端口 发现是ssh 先用ftp试试&#xff0c;尝试匿名登录 下载所有文件 发现只有一个ForMitch.txt&#xff0c;告诉我们其账号密码为弱密码&#xff0c;我们猜测Mitch为其用户名&#xff0c;尝试暴力…

MechanicalSoup,一个非常实用的 Python 自动化浏览器交互工具库!

目录 前言 什么是 Python MechanicalSoup 库&#xff1f; 核心功能 使用方法 1. 安装 MechanicalSoup 库 2. 创建 MechanicalSoup 客户端 3. 打开网页并与之交互 实际应用场景 1. 网页自动化测试 2. 网络爬虫与数据提取 3. 网页自动化操作 4. 自动化填写和提交多个表单 5.…

V-JEPA模型,非LLM另外的选择,AGI的未来:迈向Yann LeCun先进机器智能(AMI)愿景的下一步

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

EPICS和Arduino Uno之间基于串行文本协议的控制开发

Arduino Uno的串口服务程序设置如文本的串口通信协议设计以及在Arduino上的应用-CSDN博客中所示。通过在串口上发送约定的文本协议&#xff0c;它实现的功能如下&#xff1a; 实现功能&#xff1a; 读取三路0.0V~5.0V模拟量输入&#xff0c;读取端口A0~A2设置三路0.0V~5.0V的模…

typeof 与 instanceof 区别

文章目录 一、typeof二、instanceof三、区别 一、typeof typeof 操作符返回一个字符串&#xff0c;表示未经计算的操作数的类型 使用方法如下&#xff1a; typeof operand typeof(operand)operand表示对象或原始值的表达式&#xff0c;其类型将被返回 举个例子 typeof 1 /…

K8S之持久化存储

持久化存储 支持的持久化存储类型EmptyDirHostPathNFS 在K8S中部署的应用都是以pod容器的形式运行的&#xff0c;假如部署数据库服务 例如&#xff1a;MySQL、Redis等&#xff0c;需要对产生的数据做备份。如果pod不挂载数据卷&#xff0c;那pod被删除或重启后这些数据会随之消…

Windows server Database 2025 安装 i225/i226 网卡驱动

windows这比坏得很&#xff0c;intel消费级网卡不准在服务器系统上安装。你要说他是异构不支持&#xff1f;他就纯粹恶心人。 之前已经安装过一次&#xff0c;但是今天database预览版一更新&#xff0c;又给我把网卡驱动杀了&#xff0c;气死&#xff0c;写一篇教程。 1.去官网…

SQLite优化实践:数据库设计、索引、查询和分库分表策略

文章目录 一、数据库设计优化1.1 合理选择数据类型1.2 使用NOT NULL约束1.3 使用默认值1.4 避免使用过多的列 二、索引优化2.1 为经常用于查询条件的列创建索引2.2 为经常用于排序和分组的列创建索引2.3 避免过多的索引2.4 使用覆盖索引 三、查询优化3.1 使用预编译语句3.2 优化…