基础32中Java的BigInteger C#

时间:2016-08-09 17:13:47

标签: java c# random biginteger base32

如何将以下Java行转换为C#。它生成一个大小为130位的随机BigInteger,将其转换为基数为32的字符串(即 not decimal ),然后操作字符串:

new BigInteger(130, new SecureRandom()).toString(32).replace("/", "w").toUpperCase(Locale.US);

如何在C#中实现这一目标?

  • 生成随机130位BigInteger
  • 将其转换为基数为32的字符串

就随机BigInteger而言,我有这个功能:

static BigInteger RandomInteger(int bits)
{
            RNGCryptoServiceProvider secureRandom = new RNGCryptoServiceProvider();
            // make sure there is extra room for a 0-byte so our number isn't negative
            // in the case that the msb is set
            var bytes = new byte[bits / 8 + 1];
            secureRandom.GetBytes(bytes);
            // mask off excess bits
            bytes[bytes.Length - 1] &= (byte)((1 << (bits % 8)) - 1);
            return new BigInteger(bytes);
}

取自此问题,该问题未涉及基本转换:Equivalent of Java's BigInteger in C#

但是我不确定该功能是否也正确。

我到目前为止的C#代码,RandomInteger是上述功能:

RandomInteger(130).ToString().Replace("/","w").ToUpper(CultureInfo.GetCultureInfo("en-US"));

2 个答案:

答案 0 :(得分:1)

上面的代码有很多错误,如果位是完整的,最后一个数字被完全屏蔽掉,并且数字变为正数的可能性因为新的BigInteger(byte [])重载需要一个小的endian签名数字,所以你必须用0字节前缀

    static BigInteger RandomInteger(int bits)
    {
        var bytes = new byte[(bits + 7) / 8 + 1];

        using (var rng = new RNGCryptoServiceProvider())
            rng.GetBytes(bytes, 0, bytes.Length - 1);

        var remainingBits = bits % 8;

        if (remainingBits > 0)
            bytes[bytes.Length - 2] &= (byte)((1 << remainingBits) - 1);

        return new BigInteger(bytes);
    }

我认为这会起作用

答案 1 :(得分:1)

Base 32 string

这就是我将如何转换为base 32.请注意,我不能在这里测试它并且我的C#有点生疏,但我认为以下内容应该足以让你前进(如果有人看到语法错误,请编辑出来):

static string BigIntegerToString32(BigInteger bi)
{
    // Obvious shortcut -- avoids problems later on.
    if (bi == BigInteger.Zero)
        return("0");

    readonly char[] digits = new char[] { 
        '0', '1', '2', '3', '4', '5', '6', '7',
        '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
        'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
        'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V'
    };

    // Only work with positive BigInteger.
    BigInteger value = BigInteger.Abs(bi);

    // Collects one digit on each iteration.
    StringBuilder result = new StringBuilder();

    // This value is needed more often -- only converted once.
    BigInteger thirtyOne = 0x1F;

    while (value > BigInteger.Zero)
    {   
        // get next digit: value % 32  
        result.Insert(0, digits[(int)(value & thirtyOne)]);

        // shift out last digit: value = value / 32
        value >>= 5;
    }

    // prepend '-' if negative
    if (bi < BigInteger.Zero)
        result.Insert(0, '-');

    return result.ToString();
}

请注意,对于巨大的BigIntegers,使用更快但更复杂的算法(就像我在Delphi BigInteger实现中所做的那样)可能是有意义的,尽管这可能或多或少如何C#&#39; s BigInteger(对于大型BigIntegers不使用更复杂的例程,AFAIK,与Java不同)也为基数10执行此操作。

随机130位BigInteger

@ hl3mukkel的答案比你找到和发布的代码更好地生成n位随机BigInteger,所以使用他的代码生成这样的BigInteger