1

我正在尝试将使用按位运算的 C++ 函数移植到 C#,但遇到了问题。即当输入是0x01123456C# 时返回零,但它应该是12

  • BN_set_word 和其他 BN_* 函数在 OpenSSL 中。这些函数做了什么(详细)......是否有一个大整数的.NET等价物?

  • 什么是 MPI 表示?(谷歌没用)

  • 我应该担心这里评论中提到的班次计数中的掩蔽吗?

C++ 原版

Git 源代码

    // The "compact" format is a representation of a whole
    // number N using an unsigned 32bit number similar to a
    // floating point format.
    // The most significant 8 bits are the unsigned exponent of base 256.
    // This exponent can be thought of as "number of bytes of N".
    // The lower 23 bits are the mantissa.
    // Bit number 24 (0x800000) represents the sign of N.
    // N = (-1^sign) * mantissa * 256^(exponent-3)
    //
    // Satoshi's original implementation used BN_bn2mpi() and BN_mpi2bn().
    // MPI uses the most significant bit of the first byte as sign.
    // Thus 0x1234560000 is compact (0x05123456)
    // and  0xc0de000000 is compact (0x0600c0de)
    // (0x05c0de00) would be -0x40de000000
    //
    // Bitcoin only uses this "compact" format for encoding difficulty
    // targets, which are unsigned 256bit quantities.  Thus, all the
    // complexities of the sign bit and using base 256 are probably an
    // implementation accident.
    //
    // This implementation directly uses shifts instead of going
    // through an intermediate MPI representation.
    CBigNum& SetCompact(unsigned int nCompact)
    {
        unsigned int nSize = nCompact >> 24;
        bool fNegative     =(nCompact & 0x00800000) != 0;
        unsigned int nWord = nCompact & 0x007fffff;
        if (nSize <= 3)
        {
            nWord >>= 8*(3-nSize);
            BN_set_word(this, nWord);
        }
        else
        {
            BN_set_word(this, nWord);
            BN_lshift(this, this, 8*(nSize-3));
        }
        BN_set_negative(this, fNegative);
        return *this;
    }

C# 尝试的端口

    internal static System.Numerics.BigInteger SetCompact(uint numToCompact)
    {
        //
        //
        //  SetCompact
        // Extract the number from bits 0..23
        uint nWord = numToCompact & 0x007fffff;
        BigInteger ret = new BigInteger(nWord);

        // Add zeroes to the left according to bits 25..32
        var ttt =  ret.ToByteArray();
        uint size = numToCompact >> 24;
        uint amountToShift = 0;
        if (size <= 3)
        {
            amountToShift = 8 * (3 - size);
            ret = ret >> (int)amountToShift;
        }
        else
        {
            ret = ret << (int)amountToShift;
            amountToShift = 8 * (size - 3);
        }

        // Set the value negative if required per bit 24
        UInt32 isNegative = 0x00800000 & numToCompact;
        if (isNegative != 0)
            ret =BigInteger.Negate(ret);

        var test = ret.ToByteArray();
        Console.WriteLine();
        Console.WriteLine(ret.ToString("X"));
        return ret;

    }
4

0 回答 0