using System; using System.IO; namespace AssetBundleHub { public class XORCryptStream : Stream { Stream baseStream; byte[] key; public XORCryptStream(Stream baseStream, byte[] key) { this.baseStream = baseStream; this.key = key; } public override bool CanRead => baseStream.CanRead; public override bool CanSeek => baseStream.CanSeek; public override bool CanWrite => baseStream.CanWrite; public override long Length => baseStream.Length; public override long Position { get { return baseStream.Position; } set { baseStream.Position = value; } } public override void Flush() => baseStream.Flush(); public override long Seek(long offset, SeekOrigin origin) => baseStream.Seek(offset, origin); public override void SetLength(long value) => baseStream.SetLength(value); /// /// 復号化しつつ読む /// /// 結果を格納するbuffer /// bufferのoffset番目から格納 /// 何byte読み込むか /// 読み取ったbyte数を返す public override int Read(byte[] buffer, int offset, int count) { var startPosition = Position; int readCount = baseStream.Read(buffer, offset, count); int keyIndex = (int)(startPosition % key.Length); for (int i = 0; i < readCount; i++) { int bufferIndex = i + offset; if (keyIndex == key.Length) { keyIndex = 0; } buffer[bufferIndex] ^= key[keyIndex]; // xor keyIndex++; } return readCount; } public override void Write(byte[] buffer, int offset, int count) { if (buffer.Length < offset + count) { throw new ArgumentException("offset + count is larger than buffer.Length"); } byte[] writeBuffer = new byte[count]; var startPosition = Position; int keyIndex = (int)(startPosition % key.Length); for (int i = 0; i < count; i++) { int bufferIndex = i + offset; if (keyIndex == key.Length) { keyIndex = 0; } writeBuffer[i] = buffer[bufferIndex]; writeBuffer[i] ^= key[keyIndex]; keyIndex++; } baseStream.Write(writeBuffer, 0, count); } } }