Skip to content

Instantly share code, notes, and snippets.

@progalgo
Created November 24, 2021 09:35
Show Gist options
  • Save progalgo/46b315caa7947c04f264bbb497f60d89 to your computer and use it in GitHub Desktop.
Save progalgo/46b315caa7947c04f264bbb497f60d89 to your computer and use it in GitHub Desktop.
.NET Stream, that gives random bytes. Not cryptographically secure.
using System;
using System.IO;
class RandomStream : Stream
{
private readonly Random rng;
private long position = 0;
private readonly object advanceLock = new object();
public RandomStream(Random rng, long length)
{
this.rng = rng;
Length = length;
}
public RandomStream(int seed, long length)
{
rng = new Random(seed);
Length = length;
}
public RandomStream(long length)
{
rng = new Random();
Length = length;
}
public override bool CanRead => true;
public override bool CanSeek => false;
public override bool CanWrite => false;
public override long Length { get; }
public override long Position
{
get => position;
set => throw new InvalidOperationException();
}
private int Advance(int count)
{
lock (advanceLock)
{
var remaining = Length - Position;
int advance = (int)Math.Min(count, remaining);
position += advance;
return advance;
}
}
public override int Read(byte[] buffer, int offset, int count)
{
if (buffer is null)
throw new ArgumentNullException(nameof(buffer));
checked
{
if (count + offset > buffer.Length)
throw new ArgumentException("Buffer too small for given offset and count");
}
if (offset < 0)
throw new ArgumentOutOfRangeException(nameof(offset));
if (count < 0)
throw new ArgumentOutOfRangeException(nameof(count));
var advance = Advance(count);
lock (rng)
{
for (int i = 0; i < count; i++)
{
buffer[offset + i] = (byte)(rng.Next() % (Byte.MaxValue + 1));
}
}
return advance;
}
public override void Write(byte[] buffer, int offset, int count)
=> throw new InvalidOperationException();
public override long Seek(long offset, SeekOrigin origin)
=> throw new InvalidOperationException();
public override void SetLength(long value)
=> throw new InvalidOperationException();
public override void Flush()
=> throw new InvalidOperationException();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment