C# 将字节数组转换为一个十进制数作为字符串

C# 将字节数组转换为一个十进制数作为字符串,c#,.net,C#,.net,我试图编写一个函数,将任意大的字节数组(大于64位)转换为十进制数,在c#中表示为字符串,但我根本不知道该怎么做 例如,下面的代码 Console.WriteLine(ConvertToString( new byte[] { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00 })); 。。应该打印出来 2277445383

我试图编写一个函数,将任意大的字节数组(大于64位)转换为十进制数,在c#中表示为字符串,但我根本不知道该怎么做

例如,下面的代码

Console.WriteLine(ConvertToString(
  new byte[]
  { 
    0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 
    0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00
  }));
。。应该打印出来

22774453838368691933757882222884355840
我不想仅仅使用一个额外的库来实现这一点,因为我希望它简单易懂。

能满足您的需要吗?

一些指导原则:

  • 您需要将数字的数字保存在矩阵中,每个数字一个空格。矩阵开始是空的
  • 然后需要一个矩阵来保存矩阵的乘法。它也是空的
  • 现在,对于每个字节:
  • 首先,将当前数字矩阵的每个数字乘以256,将10模保存在相应的临时数字中,并将除以10的数字与下一个数字相乘
  • 将临时乘法矩阵分配给当前数字矩阵
  • 然后将字节添加到第一个数字
  • 更正当前矩阵,仅保存每个索引中的10模,并将值除以10传递给下一个索引
  • 然后,您需要将每个数字串接在一个字符串中
  • 返回字符串
  • 不要忘记根据需要展开每个矩阵,或者根据传递的字节数确定所需的最大大小

    按照上述第三步编辑示例:

    值=[0xAA,0xBB] 初始电流=[] 初始温度=[]

    带0xAA

  • 没什么可乘的
  • 任务不变
  • 我们将0xAA添加到current:current=[170]中的第一个值
  • 我们校正电流以仅保存模数,将值除以10传递给下一个值:
  • 第1位:电流=[0]通过17
  • 第二位:电流=[0,7]通过1
  • 第三位:当前=[0,7,1]没有要传递的值,因此进程结束
  • 现在使用0xBB

  • 乘以256,保存在temp中并更正,对每个数字执行以下操作:
  • 第1位:临时=[0],0保存到下一位
  • 第二位数字:校正前温度=[01792],校正后温度=[01792],179通过
  • 第三位数字:校正前温度=[0,2,1*256+179=435],校正后温度=[0,2,5],43通过
  • 第四位数字:前临时=[0,2,5,43],后临时=[0,2,5,3],3
  • 第5位数字:校正前后的Temp=[0,2,5,3,4],没有要保存的数字,因此乘法结束
  • 将温度分配到电流:电流=[0,2,5,3,4];温度=[]
  • 将当前值添加到第一个数字:当前=[187,2,5,3,4]
  • 更正以下值:
  • 第1位:当前=[7,2,5,3,4],18位通过
  • 第二位:电流=[7,0,5,3,4],2通过
  • 第三位:当前=[7,0,7,3,4],无需传递任何内容,因此加法结束

  • 现在,我们只需要将结果43707连接起来。

    您想了解工作原理,请看《超级酷》

    此外,我已经将该类剥离为这个问题的基本内容。它可以进一步优化。:)

    请尝试复制并粘贴以下代码,它可以工作

    using System;
    
    public class BigInteger
    {
        // maximum length of the BigInteger in uint (4 bytes)
        // change this to suit the required level of precision.
    
        private const int maxLength = 70;
    
    
        private uint[] data = null;             // stores bytes from the Big Integer
        public int dataLength;                 // number of actual chars used
    
    
        public BigInteger()
        {
            data = new uint[maxLength];
            dataLength = 1;
        }
    
        public BigInteger(long value)
        {
            data = new uint[maxLength];
            long tempVal = value;
    
            dataLength = 0;
            while (value != 0 && dataLength < maxLength)
            {
                data[dataLength] = (uint)(value & 0xFFFFFFFF);
                value >>= 32;
                dataLength++;
            }
    
            if (tempVal > 0)         // overflow check for +ve value
            {
                if (value != 0 || (data[maxLength - 1] & 0x80000000) != 0)
                    throw (new ArithmeticException("Positive overflow in constructor."));
            }
            else if (tempVal < 0)    // underflow check for -ve value
            {
                if (value != -1 || (data[dataLength - 1] & 0x80000000) == 0)
                    throw (new ArithmeticException("Negative underflow in constructor."));
            }
    
            if (dataLength == 0)
                dataLength = 1;
        }
    
        public BigInteger(ulong value)
        {
            data = new uint[maxLength];
    
            // copy bytes from ulong to BigInteger without any assumption of
            // the length of the ulong datatype
    
            dataLength = 0;
            while (value != 0 && dataLength < maxLength)
            {
                data[dataLength] = (uint)(value & 0xFFFFFFFF);
                value >>= 32;
                dataLength++;
            }
    
            if (value != 0 || (data[maxLength - 1] & 0x80000000) != 0)
                throw (new ArithmeticException("Positive overflow in constructor."));
    
            if (dataLength == 0)
                dataLength = 1;
        }
    
        public BigInteger(BigInteger bi)
        {
            data = new uint[maxLength];
    
            dataLength = bi.dataLength;
    
            for (int i = 0; i < dataLength; i++)
                data[i] = bi.data[i];
        }
    
        public BigInteger(byte[] inData)
        {
            dataLength = inData.Length >> 2;
    
            int leftOver = inData.Length & 0x3;
            if (leftOver != 0)         // length not multiples of 4
                dataLength++;
    
    
            if (dataLength > maxLength)
                throw (new ArithmeticException("Byte overflow in constructor."));
    
            data = new uint[maxLength];
    
            for (int i = inData.Length - 1, j = 0; i >= 3; i -= 4, j++)
            {
                data[j] = (uint)((inData[i - 3] << 24) + (inData[i - 2] << 16) +
                                 (inData[i - 1] << 8) + inData[i]);
            }
    
            if (leftOver == 1)
                data[dataLength - 1] = (uint)inData[0];
            else if (leftOver == 2)
                data[dataLength - 1] = (uint)((inData[0] << 8) + inData[1]);
            else if (leftOver == 3)
                data[dataLength - 1] = (uint)((inData[0] << 16) + (inData[1] << 8) + inData[2]);
    
    
            while (dataLength > 1 && data[dataLength - 1] == 0)
                dataLength--;
    
            //Console.WriteLine("Len = " + dataLength);
        }
    
        public override string ToString()
        {
            return ToString(10);
        }
    
        public string ToString(int radix)
        {
    
            string charSet = "ABCDEF";
            string result = "";
    
            BigInteger a = this;
    
            BigInteger quotient = new BigInteger();
            BigInteger remainder = new BigInteger();
            BigInteger biRadix = new BigInteger(radix);
    
            if (a.dataLength == 1 && a.data[0] == 0)
                result = "0";
            else
            {
                while (a.dataLength > 1 || (a.dataLength == 1 && a.data[0] != 0))
                {
                    singleByteDivide(a, biRadix, quotient, remainder);
    
                    if (remainder.data[0] < 10)
                        result = remainder.data[0] + result;
                    else
                        result = charSet[(int)remainder.data[0] - 10] + result;
    
                    a = quotient;
                }
            }
    
            return result;
        }
    
        private static void singleByteDivide(BigInteger bi1, BigInteger bi2,
                                             BigInteger outQuotient, BigInteger outRemainder)
        {
            uint[] result = new uint[maxLength];
            int resultPos = 0;
    
            // copy dividend to reminder
            for (int i = 0; i < maxLength; i++)
                outRemainder.data[i] = bi1.data[i];
            outRemainder.dataLength = bi1.dataLength;
    
            while (outRemainder.dataLength > 1 && outRemainder.data[outRemainder.dataLength - 1] == 0)
                outRemainder.dataLength--;
    
            ulong divisor = (ulong)bi2.data[0];
            int pos = outRemainder.dataLength - 1;
            ulong dividend = (ulong)outRemainder.data[pos];
    
            if (dividend >= divisor)
            {
                ulong quotient = dividend / divisor;
                result[resultPos++] = (uint)quotient;
    
                outRemainder.data[pos] = (uint)(dividend % divisor);
            }
            pos--;
    
            while (pos >= 0)
            {
                dividend = ((ulong)outRemainder.data[pos + 1] << 32) + (ulong)outRemainder.data[pos];
                ulong quotient = dividend / divisor;
                result[resultPos++] = (uint)quotient;
    
                outRemainder.data[pos + 1] = 0;
                outRemainder.data[pos--] = (uint)(dividend % divisor);
            }
    
            outQuotient.dataLength = resultPos;
            int j = 0;
            for (int i = outQuotient.dataLength - 1; i >= 0; i--, j++)
                outQuotient.data[j] = result[i];
            for (; j < maxLength; j++)
                outQuotient.data[j] = 0;
    
            while (outQuotient.dataLength > 1 && outQuotient.data[outQuotient.dataLength - 1] == 0)
                outQuotient.dataLength--;
    
            if (outQuotient.dataLength == 0)
                outQuotient.dataLength = 1;
    
            while (outRemainder.dataLength > 1 && outRemainder.data[outRemainder.dataLength - 1] == 0)
                outRemainder.dataLength--;
        }
    
    
    
        public static void Main(string[] args)
        {
    
            BigInteger big = new BigInteger(    new byte[]
                                      { 
                                        0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 
                                        0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00
                                      });
    
            Console.WriteLine(big);
    
        }
    
    }
    
    使用系统;
    公共类BigInteger
    {
    //以uint为单位的BigInteger的最大长度(4字节)
    //更改此选项以适应所需的精度级别。
    私有常量int maxLength=70;
    private uint[]data=null;//存储大整数中的字节
    public int dataLength;//实际使用的字符数
    公共BigInteger()
    {
    数据=新uint[maxLength];
    数据长度=1;
    }
    公共BigInteger(长值)
    {
    数据=新uint[maxLength];
    长tempVal=值;
    数据长度=0;
    while(值!=0&&dataLength>=32;
    dataLength++;
    }
    if(tempVal>0)//溢出检查+ve值
    {
    如果(值!=0 | |(数据[maxLength-1]&0x8000000)!=0)
    抛出(新的算术异常(“构造函数中的正溢出”);
    }
    else if(tempVal<0)//对-ve值进行下溢检查
    {
    如果(值!=-1 | |(数据[dataLength-1]&0x8000000)==0)
    抛出(新的算术异常(“构造函数中的负下溢”);
    }
    如果(数据长度==0)
    数据长度=1;
    }
    公共BigInteger(ulong值)
    {
    数据=新uint[maxLength];
    //将字节从ulong复制到BigInteger,而不假设
    //ulong数据类型的长度
    数据长度=0;
    while(值!=0&&dataLength>=32;
    dataLength++;
    }
    如果(值!=0 | |(数据[maxLength-1]&0x8000000)!=0)
    抛出(新的算术异常(“构造函数中的正溢出”);
    如果(数据长度==0)
    数据长度=1;
    }
    公共BigInteger(BigInteger bi)
    {
    数据=新uint[maxLength];
    dataLength=bi.dataLength;
    对于(int i=0;i>2;
    int leftOver=inData.Length&0x3;
    if(leftOver!=0)//长度不是4的倍数
    dataLength++;
    如果(数据长度>最大长度)
    抛出(新的算术异常(“构造函数中的字节溢出”);
    数据=新uint[maxLength];
    对于(inti=inData.Length-1,j=0;i>=3;i-=4,j++)
    {
    数据[j]=(uint)((inData[i-3]1&&outQuotient.data[outQuotient.dataLength-1]==0)
    outQuotient.dataLength--;
    if(out.dataLength)==
    
    static string BytesToString(byte[] data) {
        // Minimum length 1.
        if (data.Length == 0) return "0";
    
        // length <= digits.Length.
        var digits = new byte[(data.Length * 0x00026882/* (int)(Math.Log(2, 10) * 0x80000) */ + 0xFFFF) >> 16];
        int length = 1;
    
        // For each byte:
        for (int j = 0; j != data.Length; ++j) {
            // digits = digits * 256 + data[j].
            int i, carry = data[j];
            for (i = 0; i < length || carry != 0; ++i) {
                int value = digits[i] * 256 + carry;
                carry = Math.DivRem(value, 10, out value);
                digits[i] = (byte)value;
            }
            // digits got longer.
            if (i > length) length = i;
        }
    
        // Return string.
        var result = new StringBuilder(length);
        while (0 != length) result.Append((char)('0' + digits[--length]));
        return result.ToString();
    }