1

Java の次の行を C# に変換するにはどうすればよいでしょうか。サイズが 130 ビットのランダムな BigInteger を生成し、それを base 32 (つまり、 decimal ではない) の文字列に変換してから、文字列を操作します。

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

どうすればC#でそれを達成できますか?

  • ランダムな 130 ビット BigInteger を生成する
  • base 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);
}

base 32 変換に対応していないこの質問から取得: C# での Java の BigInteger と同等

ただし、その関数も正しいかどうかはわかりません。

私がこれまでに持っているC#コード、RandomIntegerは上記の関数です:

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

2 に答える 2

1

ベース 32 文字列

これは私が 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();
}

hugeBigIntegersの場合、より高速で複雑なアルゴリズムを使用することが理にかなっていることに注意してください (私の DelphiBigInteger実装で行っているように) BigInteger。私の知る限り、Java とは異なり) ベース 10 に対してもこれを行います。

ランダムな 130 ビット BigInteger

@hl3mukkel による回答は、見つけて投稿したコードよりもn少しランダムに生成するという点ではるかに優れているため、彼のコードを使用してそのような.BigIntegerBigInteger

于 2016-08-11T13:04:55.827 に答える
1

上記のコードにはかなりの数のバグがあります。ビットが整数の場合、最後の数値が完全にマスクされ、新しい 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);
    }

これはうまくいくと思います

于 2016-08-09T19:08:47.840 に答える