生成随机字节数组而不忽略值

时间:2014-11-23 15:45:18

标签: 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;

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

4 个答案:

答案 0 :(得分:4)

使用蒙特卡罗算法可以轻松解决您的问题。这就是@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;
        }
    }
}

RandomBytes()是一个随机字节流,很简单吧?

然后我们使用Where(b => exclusions.Contains(b) == false)从我们不喜欢的流中排除任何内容。 hashset用于&#34;效率&#34;但它对byte没有帮助(因为习惯而把它放进去)。

Take(50),我们只想从流中获得50个。

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

答案 1 :(得分:0)

如果该号码不太可能继续出现,您可以继续尝试直到产生“好”号码。

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

另外,请确保声明Random对象并反复使用它,不要继续实例化一个新对象,因为默认情况下种子是从时间中获取的,如果你一个接一个地实例化两个randoms,他们会生成相同的数字。

答案 2 :(得分:0)

您可以在单独的数组中生成允许值(相对于最小值,最大值和忽略的值),并将其用于生成目标数组。让我们考虑以下示例。

帮助功能:

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;
}

用法:

void Main()
{
  var random = new Random(42);
  var allowableValues = GenerateAllowableValues(10, 20, new byte[] { 12, 15 });
  var randomArray = GenerateRandomArray(random, allowableValues, 5);
  foreach (byte b in randomArray)
    Console.WriteLine(b); // 18 11 11 16 11
}

答案 3 :(得分:0)

构造一个你想要的字节数组,排除你不需要的字节,然后从该数组中挑选一个随机元素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)];
}