/// <summary> /// 封装数据包 /// </summary> /// <param name="data"></param> /// <returns></returns> private byte[] MakeData(byte[] data) { byte[] retBuffer = null; //1.判断是否压缩 bool isCompress = data.Length > mCompressLen ? true : false; if (isCompress)//进行压缩 { data = ZlibHelper.DeCompressBytes(data); } //2.先异或 data = SecurityUtil.Xor(data); //3.校验 ushort crc = Crc16.CalculateCrc16(data); using (ByteMemoryStream ms = new ByteMemoryStream()) { ms.WriteUShort((ushort)(data.Length + 3)); ms.WriteBool(isCompress); ms.WriteUShort(crc); ms.Write(data, 0, data.Length); retBuffer = ms.ToArray(); } return(retBuffer); }
/// <summary> /// Encode given data using LZ coding and given dictionary /// </summary> /// <param name="input">Byte array to encode</param> /// <param name="encoderDic">Dictionary implementation</param> /// <returns>Encoded byte array</returns> private static byte[] _asLZEncoded(this byte[] input, ILZ78CodingTable <int> encoderDic) { var twoPass = true; for (int i = 0; i < 256; i++) { var searchKey = new[] { (byte)i }; var codeWord = i; encoderDic.Insert(searchKey, codeWord); } var addedCodeWords = 0; using (var encodedOutput = new ByteMemoryStream((int)(input.Length / 0.6))) { var P = new byte[] { input[0] }; for (int i = 1; i < input.Length; i++) { var C = new byte[] { input[i] }; var PC = P.Concatenate(C); var item = encoderDic.Search(PC); if (item != null) { P = PC; } else { var item2 = encoderDic.Search(P); encodedOutput.AddBytes(item2.CodeWord.AsBytes()); addedCodeWords++; encoderDic.Insert(PC, encoderDic.Count); P = C; } } var item3 = encoderDic.Search(P); encodedOutput.AddBytes(item3.CodeWord.AsBytes()); addedCodeWords++; var encodedBytes = encodedOutput.ReadBytes(); if (twoPass) { return(encodedBytes.AsCompressed(encoderDic.Count - 1, addedCodeWords)); } else { return(encodedBytes); } } }
/// <summary> /// Compress bytes using .Net Core impl. of GZip /// Just for benchmark reason /// </summary> /// <param name="image"></param> /// <returns></returns> public static GZipImageFrame AsGZipEncoded <T>(this T image) where T : ImageFrame { var ret = default(byte[]); using (var outputMs = new ByteMemoryStream(1024)) { using (GZipStream compressionStream = new GZipStream(outputMs.MemoryStream, CompressionMode.Compress)) using (var inputMs = new ByteMemoryStream(image.Image)) { inputMs.MemoryStream.CopyTo(compressionStream); } ret = outputMs.ReadBytes(); } return(new GZipImageFrame(ret)); }
/// <summary> /// Decodes LZ compressed bytes /// </summary> /// <param name="codes">Compressed bytes</param> /// <param name="decoderDic">Dictionary to use in decoding</param> /// <returns>Decompressed data</returns> private static byte[] _asLZDecoded(byte[] codes, ILZ78CodingTable <byte[]> decoderDic) { for (int i = 0; i < 256; i++) { var searchKey = i.AsBytes(); var codeWord = new[] { (byte)i }; decoderDic.Insert(searchKey, codeWord); } //decompress compressed codes as int 32 byte array var decompressedCodes = codes.AsDecompressed(); using (var decodedOutPut = new ByteMemoryStream(decompressedCodes.Length * 2)) { var O = decompressedCodes.AsInt(0).AsBytes(); var S = new byte[0]; var C2 = new byte[0]; var item = decoderDic.Search(O); decodedOutPut.AddBytes(item.CodeWord); for (int i = 4; i < decompressedCodes.Length; i += 4) { var N = decompressedCodes.AsInt(i).AsBytes(); var itemN = decoderDic.Search(N); var itemO = decoderDic.Search(O); if (itemN == null) { S = itemO.CodeWord.Concatenate(C2); } else { S = itemN.CodeWord; } decodedOutPut.AddBytes(S); C2 = new byte[] { S[0] }; var C3 = itemO.CodeWord.Concatenate(C2); decoderDic.Insert(((decoderDic.Count)).AsBytes(), C3); O = N; } return(decodedOutPut.ReadBytes()); } }
/// <summary> /// Decodes compressed image /// </summary> /// <typeparam name="T">Type of image</typeparam> /// <param name="encodedImage">Image encoded bytes</param> /// <returns></returns> public static T AsImageFrame <T>(this GZipImageFrame encodedImage) where T : ImageFrame, new() { var ret2 = new T(); var ret = default(byte[]); using (var inputMs = new ByteMemoryStream(encodedImage.Data)) using (GZipStream decompressionStream = new GZipStream(inputMs.MemoryStream, CompressionMode.Decompress)) using (var outputMs = new ByteMemoryStream(1024)) { decompressionStream.CopyTo(outputMs.MemoryStream); ret = outputMs.ReadBytes(); } ret2.FromBytes(ret); return(ret2); }
//========================================================== private void Update() { #region 从队列获取数据 while (true) { if (m_ReceiveCount <= 5) { m_ReceiveCount++; lock (m_ReceiveQueue) { if (m_ReceiveQueue.Count > 0) { //得到队列中的数据包 byte[] buffer = m_ReceiveQueue.Dequeue(); //得到加密后的数据 byte[] bufferNew = new byte[buffer.Length - 3]; bool isCompress = false; ushort crc = 0; using (ByteMemoryStream ms = new ByteMemoryStream(buffer)) { isCompress = ms.ReadBool(); crc = ms.ReadUShort(); ms.Read(bufferNew, 0, bufferNew.Length); } //先校验 int newCrc = Crc16.CalculateCrc16(bufferNew); if (newCrc == crc) { //异或得到原始数据 bufferNew = SecurityUtil.Xor(bufferNew); if (isCompress) { bufferNew = ZlibHelper.DeCompressBytes(bufferNew); } ushort protoCode = 0; byte[] ProtoContent = new byte[bufferNew.Length - 2]; //协议编号 using (ByteMemoryStream ms = new ByteMemoryStream(bufferNew)) { protoCode = ms.ReadUShort(); ms.Read(ProtoContent, 0, ProtoContent.Length); //获取数据需要派发出去 GameEntry.Event.Broadcast(protoCode, ProtoContent); } } else { Debug.Log("校验出错,不予接受"); } } else { break; } } } else { m_ReceiveCount = 0; break; } } #endregion }