【问题标题】:Generate random 128 bit number生成随机 128 位数字
【发布时间】:2013-05-05 16:29:19
【问题描述】:

我正在处理一项学校作业,其中一项要求是生成一个随机的 128 位数字。 我想知道如何在 C# 中做到这一点,这种方法可以工作吗?

byte[] RND128NUMBYTE = new byte[128];
Random Rand = new Random();
Rand.NextBytes(RND128NUMBYTE);

提前谢谢大家

编辑:首先,感谢大家的回答。 无论如何,如果我明确分配会更好:我正在以安全的方式构建服务器/客户端应用程序。 用户连接到服务器后,要与连接到该服务器的其他用户通信,必须对其进行身份验证。用户向服务器询问身份验证,服务器用 128 位随机数回答客户端。之后将完成一些其他过程。

【问题讨论】:

  • 那是 128 字节,而不是 128 位。
  • 128 字节超出您的要求 8 倍。
  • 是的 byte[] RND128NUMBYTE = new byte[128**/8**]; 会起作用,但我认为这不是你分配的目的。
  • @HenkHolterman 谢谢你的回答。但我在 msdn 中读到:“这样的标识符被复制的可能性非常低。”。这是否意味着 GUID 是随机生成的?
  • @HenkHolterman:Guid 是独特性的来源,而不是随机性。是的,第 4 版 guid 的某些位是伪随机的,但并非全部都是。 NewGuid 不保证返回版本 4 的 guid,它只保证返回一个 guid。不要像这样使用“标签外”的指导;如果您没有使用它来保证唯一性,那么您可能做错了什么。

标签: c#


【解决方案1】:

数组的大小以元素为单位。因此,对于一个字节数组,您需要 16 个元素,每个元素 8 位,而不是 128 个元素。

您可以使用System.Random.NextBytesRNGCryptoServiceProvider.GetBytes

System.Random.NextBytes 可能不是一个好的选择,因为System.Random 的不良播种意味着您无法获得随机 128 位数字所期望的属性。例如,即使生成的数字少于 2^64,您也很可能会发生冲突。来自良好 PRNG 的 128 位数字与 GUID 一样具有全球唯一性,而来自System.Random 的数字肯定不是。

byte[] bytes = new byte[16];
using(var rng = new RNGCryptoServiceProvider())
{
    rng.GetBytes(bytes);
}

【讨论】:

    【解决方案2】:

    首先,您生成的是 128 个随机字节,而不是随机位。但你的澄清让一切变得不同:

    我正在以安全的方式构建服务器/客户端应用程序。用户连接到服务器后,要与连接到该服务器的其他用户通信,必须对其进行身份验证。用户向服务器询问身份验证,服务器以 128 位随机数回答客户端。

    在这种情况下,您的解决方案是非常非常错误的,即使您考虑到您生成了八倍多的位这一事实。 System.Random 只是伪随机事实上,在你做种子时只有 31 位熵。 (*) 为了安全起见,您需要所有 128 位熵。

    请记住,每一个缺失的部分都会使问题变得容易攻击一半;如果您需要 128 位熵而您有 31 位,那么问题就不是 倍更容易攻击。问题是 2128-31 = 1029 倍更容易攻击!

    巧合的是,我刚刚写了一篇关于此的博客文章。我挑战读者找出我用Random洗过的一副牌的其余部分,当时只给出了前五六张牌。有人在几个小时内通过蛮力找到了解决方案。 随机非常弱。。见http://ericlippert.com/2013/05/06/producing-permutations-part-seven/

    如果您需要安全系统的加密强度随机性,那么您需要使用具有超过 128 位熵的特殊用途随机源。

    因此 CodeInChaos 的答案是正确的。

    这个故事有两个寓意:

    首先,这就是设计安全系统如此困难的原因。有太多细节需要正确处理,您必须全部正确处理,否则系统不安全。

    其次,确保您在问题中提供足够的信息以获得好的答案。


    (*) 事实上,它的数量远少于此,因为这 231 个可能的种子中的一些比其他种子更有可能。

    【讨论】:

    • 感谢 Eric 的精彩评论……我正在迈出进入这类安全系统的第一步,所以我还是个新手。 (以及 c# 中的 alos :D )但无论如何我正在阅读您的博客,非常有趣:)。您说 CodeInChaos 的解决方案是正确的,经过您的解释,我明白为什么了。再次感谢你们俩
    • 再问一个问题,如果我想可视化这个数字,我应该使用 BigInteger 吗?我的意思是这样:BigInteger bigInt = new BigInteger(bytes);。如果返回带有 - 号的数字,这是否正确?
    • @Francesco:你当然可以使用 BigInteger。不过,我更倾向于BitConverter.ToString(byteArray);,请参阅msdn.microsoft.com/en-us/library/… 获取文档。在处理字节数组时,十六进制字符串通常比十进制更有用。此外,请尝试将字节数组视为128 位的序列,而不是整数的编码。如果它在逻辑上不被视为整数,则将其视为位。
    【解决方案3】:

    不知道作业是关于什么的吗?

    这样做:
    实施你的理论。多次运行它并存储结果。对其进行一些统计,例如检查最低和最高值以了解您是否在限制范围内。额外计算每个结果并确保它们分布均匀。

    【讨论】:

      【解决方案4】:

      要求是生成一个随机的128位数字

      我认为这个任务有点太苛刻了,我希望他们的意思是pseudo-random number。我想指出,您必须将问题分解为您理解的部分。

      你已经正确地初始化了一个PRNG并且知道如何让它fill a byte array

      Random Rand = new Random();
      Rand.NextBytes(RND128NUMBYTE);
      

      现在你需要随机填充一个 128 位的空间。什么是 128 位,.NET 或 C# 是否为您提供对位的访问?不是直接的,但你有一个byte 类型。这种类型使用 8 位,因此您只需要 128 / 8 = 16 个字节。

      你快到了,你只需要创建一个 16 字节而不是 128 字节的数组:

      byte[] RND128NUMBYTE = new byte[16];
      

      如何将convert 这些字节转换为“数字”,我会交给你。

      【讨论】:

      • This stores 128 bits 应该是 This stores 8 bits
      猜你喜欢
      • 2014-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-06
      • 1970-01-01
      • 2014-03-19
      相关资源
      最近更新 更多