Java's BigInteger C# in Base 32
本文关键字:in Base BigInteger Java | 更新日期: 2023-09-27 18:01:27
如何将下面的Java行转换为c# ?它生成一个130位大小的随机BigInteger,将其转换为32进制的字符串(即而不是十进制),然后操作字符串:
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);
}
取自一个没有解决32进制转换的问题:相当于c#中的Java's BigInteger
但是我不确定这个函数是否正确。
到目前为止我的c#代码,RandomInteger是上面描述的函数:
RandomInteger(130).ToString().Replace("/","w").ToUpper(CultureInfo.GetCultureInfo("en-US"));
上面的代码有很多错误,如果位是整的,最后一个数字会被完全掩盖,并且有可能这个数字会变成正数,因为新的BigInteger(byte[])重载期望一个小的端序符号数,所以你必须在它前面加上一个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);
}
我想这是可行的
Base 32 string
这就是我将如何转换为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#的BigInteger
(它不使用更复杂的例程来处理大的BigIntegers, AFAIK,不像Java)也这样做,以10为基数。
随机130位BigInteger
@hl3mukkel的答案在生成n
位随机BigInteger
方面比你发现和发布的代码要好得多,所以使用他的代码来生成这样的BigInteger
。