Преобразование побитовых операций C ++ и OpenSSL BigNumber в C #

Я пытаюсь портировать функцию C ++, которая использует побитовые операции, на C #, но сталкиваюсь с проблемами. А именно, когда вход 0x01123456 C # возвращает ноль, но так должно быть 12

  • BN_set_word и другие функции BN_ * находятся в OpenSSL. Что делают эти функции (подробно) … Есть ли .NET-эквивалент в большом целом числе?

  • Что такое представление MPI? (Google бесполезен)

  • Должен ли я беспокоиться о маскировке в смене как уже упоминалось в комментариях здесь?

C ++ Original

Git Source

    // 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;

}

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …