12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- using System;
- using System.IO;
- using System.IO.Compression;
- using System.Linq;
- using System.Security.Cryptography;
- namespace UdPunching
- {
- public static class TransferCodec
- {
- // [0.....15] GUID PeerId
- // [16....17] Encrypted data length prefix (LeInt16)
- // [18...END] Encrypted data content
- public static Guid ReadId(byte[] recvData)
- {
- return new Guid(recvData.Take(16).ToArray());
- }
- public static byte[] DecodeData(RSACryptoServiceProvider localKey, byte[] recvData)
- {
- recvData.ReadLeInt16(out var len, 16);
- var raw = recvData.Skip(18).Take(len).ToArray();
- var decompressed = Decompress(raw);
- var decodeData = localKey.Decrypt(decompressed, false);
- return decodeData;
- }
- public static byte[] Encode(RSACryptoServiceProvider receiverKey, Guid id, byte[] data)
- {
- var encryptedBytes = receiverKey.Encrypt(data, false);
- var compressedData = Compress(encryptedBytes);
- var buf = new byte[16 + 2 + compressedData.Length];
- var ptr = -1;
- ptr += id.WriteTo(buf, ++ptr); // 16
- ptr += compressedData.Length.WriteLeInt16To(buf, ++ptr); // 2
- compressedData.WriteTo(buf, ++ptr);
- return buf;
- }
- private static byte[] Compress(byte[] data)
- {
- using (var rawIn = new MemoryStream(data))
- using (var gzOut = new MemoryStream())
- using (var gZipStream = new GZipStream(gzOut, CompressionLevel.Optimal))
- using (var finalOut = new MemoryStream())
- {
- rawIn.CopyTo(gZipStream);
- gZipStream.Close();
- var compressed = gzOut.ToArray();
- if (compressed.Length >= data.Length)
- {
- finalOut.WriteByte(0);
- finalOut.Write(data, 0, data.Length);
- }
- else
- {
- finalOut.WriteByte(1);
- finalOut.Write(compressed, 0, compressed.Length);
- }
- return finalOut.ToArray();
- }
- }
- private static byte[] Decompress(byte[] data)
- {
- using (var rawIn = new MemoryStream(data))
- using (var finalOut = new MemoryStream())
- {
- if (rawIn.ReadByte() == 1)
- {
- using (var gZipStream = new GZipStream(rawIn, CompressionMode.Decompress))
- {
- gZipStream.CopyTo(finalOut);
- }
- }
- else
- {
- rawIn.CopyTo(finalOut);
- }
- return finalOut.ToArray();
- }
- }
- }
- }
|