//由包头至有效数据生成CRC与收上来的数据CRC进行比较 private static bool IsCRCOK(User user, byte[] receive) { //第二步 由包头至有效数据生成CRC与收上来的数据CRC进行比较 user.checkCRC = 0; //crc校验码清零 很重要 //由收上来的数据生成CRC检验码 for (int i = 0; i < (receive.Length - 6); i++) //CRC校验 { user.checkCRC = CRCtest.CRC(receive[i], user.checkCRC); } //CRC校验 receive[receive.Length - 6]CRC高位 receive[receive.Length - 5]CRC低位 if ((receive[receive.Length - 6] == (byte)(user.checkCRC >> 8)) && ((byte)user.checkCRC == receive[receive.Length - 5])) { return(true); } else { return(false); } }
/// <summary> /// 加密封包函数(包含CRC校验) /// </summary> ///// <param name="user">对象</param> /// <param name="message">要进行封包的有效数据字符串(未进行加密)</param> /// <returns></returns> public static byte[] PacketMessage(User user, string message) { try { string path = "keyInfo.xml"; XmlDocument xd = new XmlDocument(); xd.Load(path); XmlNode root = xd.DocumentElement; byte[] key = Encoding.ASCII.GetBytes(root.SelectSingleNode("key").InnerText); //获得AES密钥 byte[] IV = Encoding.ASCII.GetBytes(root.SelectSingleNode("IV").InnerText); //获得AES初始量 // 1 对xml指令进行AES加密 形成有效数据 // byte[] key = Encoding.ASCII.GetBytes(GlobalInfo.Key);//获得AES密钥 //byte[] IV = Encoding.ASCII.GetBytes(GlobalInfo.IV);//获得AES初始量 byte[] crypted = AES.AEScryptedDataToByte(message, key, IV);//加密后的XML文本内容 //byte[] crypted = aes.AEScryptedDataToByte("1234567890123456", key, IV); //byte[] crypted = Encoding.ASCII.GetBytes(message); int count = crypted.Length + 4;//加上四个字节的指令序号 这部分构成有限数据 //2 封包 //计算有效数据长度(高位在前(command[6])) //经过计算,两个字节可以代表的最大(FFFF)65536个字节约为64k 对于发送的数据长度来说足够了 //user.command[4] = 0x00; //user.command[5] = 0x00; //user.command[6] = Convert.ToByte((int)count / 256);//有效数据除以256取整 高位字节的大小 //user.command[7] = Convert.ToByte(count - ((int)count / 256) * 256);//总长度-高位字节的大小=剩余的字节数(由低位字节表示) switch (count.ToString().Length) { case 0: user.command[4] = 0x30; user.command[5] = 0x30; user.command[6] = 0x30; user.command[7] = 0x30; break; case 1: user.command[4] = 0x30; user.command[5] = 0x30; user.command[6] = 0x30; user.command[7] = Convert.ToByte(count + 30); break; case 2: user.command[4] = 0x30; user.command[5] = 0x30; user.command[6] = Convert.ToByte(int.Parse(count.ToString().Substring(0, 1)) + 48); user.command[7] = Convert.ToByte(int.Parse(count.ToString().Substring(1, 1)) + 48); break; case 3: user.command[4] = 0x30; user.command[5] = Convert.ToByte(int.Parse(count.ToString().Substring(0, 1)) + 48); user.command[6] = Convert.ToByte(int.Parse(count.ToString().Substring(1, 1)) + 48); user.command[7] = Convert.ToByte(int.Parse(count.ToString().Substring(2, 1)) + 48); break; case 4: user.command[4] = Convert.ToByte(int.Parse(count.ToString().Substring(0, 1)) + 48); user.command[5] = Convert.ToByte(int.Parse(count.ToString().Substring(1, 1)) + 48); user.command[6] = Convert.ToByte(int.Parse(count.ToString().Substring(2, 1)) + 48); user.command[7] = Convert.ToByte(int.Parse(count.ToString().Substring(3, 1)) + 48); break; default: break; } //指令序号(四个字节) user.command[8] = 0x30; //指令序号 user.command[9] = 0x30; //指令序号 user.command[10] = 0x30; //指令序号 user.command[11] = 0x30; //指令序号 //将有效数据写入command指令 for (int i = 0; i < (count - 4); i++)//command[8+count]是第一位CRC校验 count中包含4个字节的指令序号 { user.command[12 + i] = crypted[i]; } //3 生成CRC校验码 由包头至有效数据部分生成 user.checkCRC = 0; //crc校验码清零 很重要 for (int i = 0; i < (count + 8); i++) //CRC校验 { user.checkCRC = CRCtest.CRC(user.command[i], user.checkCRC); } user.command[8 + count] = (byte)(user.checkCRC >> 8); //CRC高位 user.command[9 + count] = (byte)user.checkCRC; //CRC低位 //包尾 user.command[10 + count] = 0x55; user.command[11 + count] = 0xAA; user.command[12 + count] = 0x55; user.command[13 + count] = 0xAA; //4 截取command的有效数据(去掉未赋值的空字节) byte[] command_Result = new byte[14 + count]; for (int i = 0; i <= (13 + count); i++) { command_Result[i] = user.command[i]; } return(command_Result);//返回具有一定长度的字节数组(即发送指令) } catch { return(null); } }