C# 生成不忽略值的随机字节数组

C# 生成不忽略值的随机字节数组,c#,arrays,random,C#,Arrays,Random,这是我用来生成随机字节数组的代码。很好,唯一的问题是 有一个(或多个)号码我不想要。我的问题是,我如何确保这些不需要的数字不包含在结果中,而不必检查每个结果 Random rnd = new Random(); Byte[] bytes = new Byte[50]; rnd.NextBytes(bytes); 对于一个字节,我使用这个函数 int b = rnd.Next(min, (max + 1)) return (byte) b; 我可以控制结

这是我用来生成随机字节数组的代码。很好,唯一的问题是 有一个(或多个)号码我不想要。我的问题是,我如何确保这些不需要的数字不包含在结果中,而不必检查每个结果

    Random rnd = new Random();
    Byte[] bytes = new Byte[50];
    rnd.NextBytes(bytes);
对于一个字节,我使用这个函数

    int b = rnd.Next(min, (max + 1))
    return (byte) b;

我可以控制结果范围,但重复调用此函数不会产生好的结果。

如果数字不太可能持续出现,您可以继续尝试,直到生成“好”的数字

var badNumbers = new int[] { 244, 100 };
int b = 0;
do
{
    b = rnd.Next(min, (max + 1));
} while (badNumbers.Contains(b));

此外,请确保声明随机对象并反复使用它,不要不断实例化新对象,因为默认情况下,种子是从时间中提取的,如果您一个接一个地实例化两个随机对象太快,它们将生成相同的数字。

您可以在单独的数组中生成允许的值(关于最小值、最大值和忽略值),并将其用于目标阵列生成。 帮助功能:

byte[] GenerateAllowableValues(byte min, byte max, byte[] ignore)
{
  var list = new List<byte>();
  for (byte i = min; i <= max; i++)
    if (!ignore.Contains(i))
      list.Add(i);
  return list.ToArray();
}

byte[] GenerateRandomArray(Random random, byte[] allowableValues, int length)
{ 
  var array = new byte[length];
  for (int i = 0; i < length; i++)
    array[i] = allowableValues[random.Next(allowableValues.Length)];
  return array;
}

构造一个包含所需字节(不包括不包含的字节)的数组,然后从该数组中随机选取一个元素50次

var rnd = new Random();
var exclusions = new byte[] { 1, 200, 58, 11, 66, 9 };
var candidates = Enumerable.Range(0, 255).Where(i => !exclusions.Contains((byte)i)).ToArray();

var results = new byte[50];
for (var i = 0; i < results.Length; i++)
{
    results[i] = (byte)candidates[rnd.Next(0, candidates.Length - 1)];
}
var rnd=new Random();
var exclusions=新字节[]{120058,11,66,9};
var候选者=Enumerable.Range(0255)。其中(i=>!exclusions.Contains((byte)i)).ToArray();
var结果=新字节[50];
对于(var i=0;i
您的问题可以通过蒙特卡罗算法轻松解决。这就是@SteveLillis所做的,但这是一个不完整的答案。下面是完整的答案

void Main()
{
    var exclusions = new HashSet<byte> { 1, 200, 58, 11, 66, 9 };

    var results = RandomBytes()
                    .Where(b => exclusions.Contains(b) == false)
                    .Take(50)
                    .ToArray();
}

public IEnumerable<byte> RandomBytes()
{
    var random = new Random();
    byte[] buffer = new byte[32];
    while(true)
    {
        random.NextBytes(buffer);
        foreach(var ret in buffer)
        {
            yield return ret;
        }
    }
}
void Main()
{
var Exclutions=新哈希集{120058,11,66,9};
var results=RandomBytes()
其中(b=>Exclutions.Contains(b)==false)
.Take(50)
.ToArray();
}
公共IEnumerable RandomBytes()
{
var random=新的random();
字节[]缓冲区=新字节[32];
while(true)
{
随机。下个字节(缓冲区);
foreach(缓冲区中的var ret)
{
收益率;
}
}
}
RandomBytes()
是一个随机字节流,很简单吧

然后我们从流中排除我们不喜欢的任何内容,使用
Where(b=>exclusions.Contains(b)==false)
。哈希集是为了“效率”,但它对
byte
没有帮助(只是出于习惯把它放进去)

Take(50)
,我们只需要从流中提取50


ToArray
将结果作为数组提供给我。

您不想要的是什么数字?能否显示包含这些数字的示例输出,以及您希望它看起来是什么样子?“但是重复调用此函数不会给出好的结果。”这意味着什么?你每次调用函数都得到相同的数字吗?yield和lambda…酷@Aron!!!但我不明白为什么缓冲区数组是32?1数组足够好了,因为它是一个随机数,你不这么认为吗?@sambyte我不完全确定
.NextBytes
的实现是什么。一般来说,当它们以这种方式公开功能,通常使用“较大”的缓冲区运行更便宜。但是,是的,
byte[1]
在功能上也会完全相同。
void Main()
{
    var exclusions = new HashSet<byte> { 1, 200, 58, 11, 66, 9 };

    var results = RandomBytes()
                    .Where(b => exclusions.Contains(b) == false)
                    .Take(50)
                    .ToArray();
}

public IEnumerable<byte> RandomBytes()
{
    var random = new Random();
    byte[] buffer = new byte[32];
    while(true)
    {
        random.NextBytes(buffer);
        foreach(var ret in buffer)
        {
            yield return ret;
        }
    }
}