C# 将字节数组转换为一个十进制数作为字符串
我试图编写一个函数,将任意大的字节数组(大于64位)转换为十进制数,在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
Console.WriteLine(ConvertToString(
new byte[]
{
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00
}));
。。应该打印出来
22774453838368691933757882222884355840
我不想仅仅使用一个额外的库来实现这一点,因为我希望它简单易懂。能满足您的需要吗?一些指导原则:
现在,我们只需要将结果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();
}