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

Mar*_*tin 9 .net c#

我正在尝试编写将任意大字节数组(大于64位)转换为c#中表示为字符串的十进制数的函数,我根本无法弄清楚如何去做.

例如以下代码......

Console.WriteLine(ConvertToString(
  new byte[]
  { 
    0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 
    0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00
  }));
Run Code Online (Sandbox Code Playgroud)

..应打印出来

22774453838368691933757882222884355840
Run Code Online (Sandbox Code Playgroud)

我不想仅仅使用像biginteger这样的额外库,因为我希望它很简单并且想要了解它是如何工作的.

Wil*_*elm 6

一些准则:

  1. 您需要将数字的数字保存在矩阵中,每个数字一个空格.矩阵开始为空.
  2. 然后你需要一个矩阵来保存矩阵的乘法.它也开始空洞了.
  3. 现在,您拥有的每个字节:
    1. 首先将当前数字矩阵的每个数字乘以256,将10个模数保存在相应的临时数字中,并将数字除以10加到下一个数字乘法.
    2. 将临时乘法矩阵分配给当前数字矩阵.
    3. 然后将字节添加到第一个数字.
    4. 更正当前矩阵,仅保存每个索引中的10个模数,并将值除以10传递给下一个索引.
  4. 然后你需要连接一个字符串中的每个数字.
  5. 返回字符串.

不要忘记根据需要扩展每个矩阵,或者根据传递的字节数确定所需的最大大小.

编辑,上面第三步的示例:

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

使用0xAA

  1. 没有什么可以成倍增加.
  2. 作业没有变化.
  3. 我们将0xAA添加到当前的第一个值:Current = [170]
  4. 我们纠正当前只保存模数,将值除以10传递给下一个值:
    1. 第一位:电流= [0]通过17.
    2. 第二位:Current = [0,7]传递1.
    3. 第3位:Current = [0,7,1]没有要传递的值,因此进程结束.

现在有了0xBB

  1. 乘以256,保存在温度和正确,为每个数字做:
    1. 第一位:Temp = [0],0保存到下一位.
    2. 第2位:校正前Temp = [0,1792],Temp = [0,2],校正后经过179.
    3. 第3位:校正前Temp = [0,2,1*256 + 179 = 435],Temp = [0,2,5],校正后经过43.
    4. 第4位:Temp = [0,2,5,43]之前,Temp = [0,2,5,3],3之后传递
    5. 第5位:Temp =校正之前和之后的[0,2,5,3,4],没有要保存的数字,所以乘法结束.
  2. 将温度分配给电流:电流= [0,2,5,3,4]; 温度= []
  3. 将当前值添加到第一个数字:Current = [187,2,5,3,4]
  4. 纠正价值观:
    1. 第一位:电流= [7,2,5,3,4],18通过.
    2. 第二位:电流= [7,0,5,3,4],2通过.
    3. 第3位:电流= [7,0,7,3,4],无法通过,因此添加结束.

现在我们只需要连接结果43707.


Sim*_*han 4

基于@Wilheim 的回答:

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();
}
Run Code Online (Sandbox Code Playgroud)