这是我将字节数组转换为大十进制数的代码。
public static string ToDecimal(byte[] bytes) {
var ints = ToIntArray(bytes).Reverse();
const uint limitUnit = 1_000_000_000;
var intBuffer = new List<ulong>();
foreach (var t in ints) {
PushNewInt(intBuffer, t);
}
if (intBuffer.Count == 0) return "0";
var sb = new StringBuilder(intBuffer[^1].ToString());
for (var i = intBuffer.Count - 2; i >= 0; --i) {
sb.Append($"{intBuffer[i]:D9}");
}
return sb.ToString();
}
public static int[] ToIntArray(byte[] bytes) {
var length = bytes.Length;
while (length > 0 && bytes[length - 1] == 0) {
--length;
}
var integer = 0;
var intArray = new int[length / 4 + ((length & 3) == 0 ? 0 : 1)];
for (var i = 0; i < length; ++i) {
integer = bytes[i] << (8 * i) | integer;
if ((i & 3) != 3) continue;
intArray[i / 4] = integer;
integer = 0;
}
if (integer > 0) intArray[length / 4] = integer;
return intArray;
}
void PushNewInt(IList<ulong> buffer, int newInt) {
var added = (ulong)(uint)newInt;
for (var i = 0; i < buffer.Count; ++i) {
var upValue = buffer[i] << 32 | added;
buffer[i] = upValue % limitUnit;
added = upValue / limitUnit;
}
if (added == 0) return;
buffer.Add(added % limitUnit);
added /= limitUnit;
if (added > 0) buffer.Add(added);
}
单元测试:
public static IEnumerable<object[]> TestByteArray => new List<object[]> {
new object[] { new byte[] { 0x1, 0x2, 0x3, 0x4, 0x10, 0x11 }, new[] { 0x04030201, 0x1110 } },
new object[] { new byte[] { 0xAA, 0x0, 0x00, 0x0, 0x00, 0x00 }, new[] { 0xAA } },
new object[] {
Convert.FromHexString("B3D5482DCA7FD3956343D8BFE3CEB4"),
new[] { 0x2D48D5B3, -1781301302, -1076346013, 0xB4CEE3 }
}
};
[Theory]
[MemberData(nameof(TestByteArray))]
public void ToIntArray(byte[] bytes, int[] expected) {
var actual = Radix.ToIntArray(bytes);
Assert.Equal(expected, actual);
}
private static IEnumerable<byte[]> _toDecimalTest = new List<byte[]> {
new byte[] { 0xAA, 0x0, 0x00, 0x0, 0x00, 0x00 },
Convert.FromHexString("B3D5482DCA7FD3956343D8BFE3CEB4"),
RandomBytes(219),
new byte[]
{
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00
}
};
private static byte[] RandomBytes(int count) {
var bytes = new byte[count];
Random.Shared.NextBytes(bytes);
return bytes;
}
public static IEnumerable<object[]> ToDecimalTestData => _toDecimalTest.Select(
bytes => new object[] {
bytes, new BigInteger(bytes, isUnsigned: true).ToString()
}
);
[Theory]
[MemberData(nameof(ToDecimalTestData))]
public void ToDecimal(byte[] bytes, string expected) {
var actual = Radix.ToDecimal(bytes);
Assert.Equal(expected, actual);
}