将“大”hex数字(字符串格式)转换为十进制数字(字符串格式),不带BigInteger类

如何转换“大”hex数字(字符串格式):

EC851A69B8ACD843164E10CFF70CF9E86DC2FEE3CF6F374B43C854E3342A2F1AC3E30C741CC41E679DF6D07CE6FA3A66083EC9B8C8BF3AF05D8BDBB0AA6CB3EF8C5BAA2A5E531BA9E28592F99E0FE4F95169A6C63F635D0197E325C5EC76219B907E4EBDCD401FB1986E4E3CA661FF73E7E2B8FD9988E753B7042B2BBCA76679

到十进制数字(字符串格式):

166089946137986168535368849184301740204613753693156360462575217560130904921953976324839782808018277000296027060873747803291797869684516494894741699267674246881622658654267131250470956587908385447044319923040838072975636163137212887824248575510341104029461758594855159174329892125993844566497176102668262139513

不使用BigInteger类(因为我的应用程序应该支持没有.NET Framework 4的机器)?

这是一个快速而肮脏的实现,可以处理任意大数字。 这种实现的目的是简单,而不是性能; 因此,如果要在生产场景中使用它,应该大大优化它。

编辑 :根据DanByström实施的反十进制到hex转换进一步简化:

 static string HexToDecimal(string hex) { List dec = new List { 0 }; // decimal result foreach (char c in hex) { int carry = Convert.ToInt32(c.ToString(), 16); // initially holds decimal value of current hex digit; // subsequently holds carry-over for multiplication for (int i = 0; i < dec.Count; ++i) { int val = dec[i] * 16 + carry; dec[i] = val % 10; carry = val / 10; } while (carry > 0) { dec.Add(carry % 10); carry /= 10; } } var chars = dec.Select(d => (char)('0' + d)); var cArr = chars.Reverse().ToArray(); return new string(cArr); } 

我刚刚将道格拉斯的代码翻译成了VBA

 Function HexToDecimal(ByVal sHex As String) As String Dim dec() As Long ReDim dec(0 To 0) As Long Dim lCharLoop As Long For lCharLoop = 1 To Len(sHex) Dim char As String * 1 char = Mid$(sHex, lCharLoop, 1) Dim carry As Long carry = Val("&h" & char) Dim i As Long For i = 0 To UBound(dec) Dim lVal As Long lVal = dec(i) * 16 + carry dec(i) = lVal Mod 10 carry = lVal \ 10 Next i While (carry > 0) ReDim Preserve dec(0 To UBound(dec) + 1) As Long dec(UBound(dec)) = carry Mod 10 carry = carry \ 10 Wend Next For lCharLoop = UBound(dec) To LBound(dec) Step -1 Dim sDecimal As String sDecimal = sDecimal & Chr$(48 + dec(lCharLoop)) Next HexToDecimal = sDecimal End Function Private Sub TestHexToDecimal() Debug.Assert HexToDecimal("F") = "15" Debug.Assert HexToDecimal("4") = CStr(Val("&H4")) Debug.Assert HexToDecimal("10") = CStr(Val("&H10")) Debug.Assert HexToDecimal("20") = CStr(Val("&H20")) Debug.Assert HexToDecimal("30") = CStr(Val("&H30")) Debug.Assert HexToDecimal("40") = CStr(Val("&H40")) Debug.Assert HexToDecimal("44") = CStr(Val("&H44")) Debug.Assert HexToDecimal("FF") = "255" Debug.Assert HexToDecimal("FFF") = "4095" Debug.Assert HexToDecimal("443") = CStr(Val("&H443")) Debug.Assert HexToDecimal("443C1") = "279489" Debug.Assert HexToDecimal("443C1CE20DFD592FB374D829B894BBE5") = "90699627342249584016268008583970733029" Debug.Assert HexToDecimal("EC851A69B8ACD843164E10CFF70CF9E86DC2FEE3CF6F374B43C854E3342A2F1AC3E30" & _ "C741CC41E679DF6D07CE6FA3A66083EC9B8C8BF3AF05D8BDBB0AA6CB3EF8C5BAA2A5" & _ "E531BA9E28592F99E0FE4F95169A6C63F635D0197E325C5EC76219B907E4EBDCD401FB1" & _ "986E4E3CA661FF73E7E2B8FD9988E753B7042B2BBCA76679") = _ "1660899461379861685353688491843017402046137536931563604625752175601309049219" & _ "5397632483978280801827700029602706087374780329179786968451649489474169926767" & _ "4246881622658654267131250470956587908385447044319923040838072975636163137212" & _ "8878242485755103411040294617585948551591743298921259938445664971761026682621" & _ "39513" End Sub 

也是statman.info的基准, hex转换为大数字

您可以使用IntX库,因为它应该与.Net 2.0及更高版本一起使用。 从关于BigInteger的页面描述:

所以内部的System.Numerics.BigInteger似乎使用标准的任意算术算法,我并不担心IntX库,因为由于它使用了FHT,它对于真正的大整数来说可能快一些。

许可证非常自由,但值得一读,只是为了确保它没问题。

我没有使用过这个库,但是粗略地看一下源代码,这应该就是你需要做的

 string dec = new IntX(myHex, 16).ToString(); 

如果您不想自己编译代码,可以通过Nuget安装它。

一种简单的方法是使用支持您的.NET版本的大数据库。 我推荐GnuMpDotNet ,它使用优秀的GMP库 。 默认情况下,它以.NET 3.5为目标,但您可以将其更改为.NET 2.0而不会破坏任何内容(只需删除引用和using引用新内容的语句),因为它不使用.NET 3.5中的任何内容。 以下是使用GnuMpDotNet的示例:

 BigInt e = new BigInt(hexString, 16); string decimalStr = e.ToString(); 

请看我的答案: https : //stackoverflow.com/a/18231860/2521214

值得一看

  • 基于字符串的转换(仅限可用内存)
  • dec-> hex和hex <-dec包括在内
  • 没有使用bigint / bigreal lib
  • 支持定点字符串格式(无指数)

我刚刚将道格拉斯代码翻译成PHP:

 function BigNumberHexToDecimal($hex) { $dec = array(0); $hexLen = strlen($hex); for($h=0;$h<$hexLen;++$h) { $carry = hexdec($hex[$h]); for ($i = 0; $i < count($dec); ++$i) { $val = $dec[$i] * 16 + $carry; $dec[$i] = $val % 10; $carry = (int)($val / 10); } while ($carry > 0) { $dec[] = $carry % 10; $carry = (int)($carry / 10); } } return join("", array_reverse($dec)); } 

我刚刚将道格拉斯代码翻译成JAVA:

 public static String HexToDec(String hex) { List dec = new ArrayList(); for (int k = 0; k < hex.length(); k++) { String c = hex.charAt(k) + ""; int carry = Integer.parseInt(c, 16); for (int i = 0; i < dec.size(); ++i) { int val = dec.get(i) * 16 + carry; dec.set(i, val % 10); carry = val / 10; } while (carry > 0) { dec.add(carry % 10); carry /= 10; } } int[] out = new int[dec.size()]; for (int i = 0; i < dec.size(); i++) { out[i] = dec.get(i).intValue(); } return arrayToDecString(reverseArray(out)); } public static String arrayToDecString(int[] data) { String str = ""; for (int i = 0; i < data.length; i++) { str += data[i] + ""; } return str; } public static int[] reverseArray(int[] data) { for (int i = 0; i < data.length / 2; i++) { int temp = data[i]; data[i] = data[data.length - i - 1]; data[data.length - i - 1] = temp; } return data; }