你的位置:首页 > ASP.net教程

[ASP.net教程]任意进制转换算法


任意进制转换算法

N年没有写博客,发个进制转换的玩下,支持负数;功能属于简化版的 Convert.ToInt32 ,特点是:

1、任意位,如:0,1(二进制),0...7(八进制),0...9,A...F(16进制),0...N(N进制),或者是:!@#$%^&*(8进制,字符符号),也可以是中文。

2、8 byte 最大长度。

3、C#源码。

最近写markdown格式习惯啦,cnblogs啥时候全改掉算了,别用这个htmleditor算了。

先说明下进制转换的基础知识,不会的可以了解下,会的就别看了,后面的也别看,纯粹属于浪费时间。

 

 十六进制转十进制表                      10     15    1<--------------------------------------------------------------------0     0     0    0   0   A     F     1<--------------------------------------------------------------------16^7    16^6   16^5   16^4  16^3 16^2    16^1   16^0268435456 16777216 1048576 65536 4096 256    16    1<--------------------------------------------------------------------                      (10*256) + (15*16) + (1*1)                      =2560+240+1                      =2801

  

 十进制转十六进制表     ^19%16=3  | 0x319/16=1  | 0x1     = 0x13H

 

 十六进制到二进制快速转换 <----------------------- 2^3  2^2 2^1 2^0 8   4  2  1 <----------------------- 0xF821 = 1111 1000 0010 0001 <----------------------- 0xF = 15   = 8 + 4 + 2 + 1   = 1  1  1  1 0x8 = 8   = 8 + 0 + 0 + 0   = 1  0  0  0 0x2 = 2   = 0 + 0 + 2 + 0   = 0  0  1  0 0x1 = 1   = 0 + 0 + 0 + 1   = 0  0  0  1

 

 二进制到十六进制快速转换 <----------------------- 2^3  2^2 2^1 2^0 8   4  2  1 <----------------------- 1111 1000 0010 0001 = 0xF821 <----------------------- 1111  = 8 + 4 + 2 + 1    = 15    = 0xF 1000  = 8 + 0 + 0 + 0    = 8    = 0x8 0010  = 0 + 0 + 2 + 0    = 2    = 0x2 0001  = 0 + 0 + 0 + 1    = 1    = 0x1

 

十进制快速转换十六进制    103 = (6 * 16) + 7 = 0x67    22 = (1 * 16) + 6 = 0x16    54 = (3 * 16) + 6 = 0x36    255 = (15* 16) + 15 = 0xff    999 = (62 * 16) + 7 ~ 0x7     62= (3 * 16) + 14 ~ 0xe      = 3 ~ 0x3      = 0x3e7    9999= (624 * 16) + 15 ~ 0xF     624= (39*16) + 0 ~ 0x0     39= (2* 16) + 7 ~ 0x7      2= 2 ~ 0x2      = 0x270f    1980= (123 * 16) + 12 ~ 0xc     123= (7 * 16) + 11 ~ 0xb      7= 7 ~ 0x7      = 0x7bc

 

计算过程摆完了,下面是测试代码(代码未经优化,纯属测试):

  class MainClass  {    public static void Main (string[] args)    {            Console.WriteLine ("Test begin");      for (int n = -1230; n < 1230; n++) {        var a = n.ToString ("X");        var b = ConvertToAny (n, 0, "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F");        if (a != b) {          Console.WriteLine ("[{2}]Error:a!=b: {0} {1}", a, b, n);        } else if (n % 100 == 0) {          Console.WriteLine ("[{2}]Curr: a!=b: {0} {1} OK", a, b, n);        }      }      Console.WriteLine ("Test ok");      Console.WriteLine ("Test begin");      for (int n = -1230; n < 1230; n++) {        var hex = n.ToString ("X");        var a = Convert.ToInt32 (hex, 16);        var b = AnyToNumber (hex, "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F");        if (a != b) {          Console.WriteLine ("[{2}]Error:a!=b: {0} {1}", a, b, hex);        } else if (n % 100 == 0) {          Console.WriteLine ("[{2}]Curr: a!=b: {0} {1} OK", a, b, hex);        }      }      Console.WriteLine ("Test ok");      Console.WriteLine (ConvertToAny (int.MaxValue, 0, "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F"));    }    static int AnyToNumber (string any, string anyString = "0,1,2,3,4,5,6,7,8,9")    {      int sum = 0;      var ConversionTable = BuildConversionTable (anyString);      var ReverseTable = BuildReverseTable (anyString);      var tableBit = ConversionTable.Count;      bool negativeNumber = false;      if (any.Length == 8 && any [0] > '7') {        negativeNumber = true;        //反转        var res = any;        any = "";        var moveBit = tableBit - 1;        foreach (var c in res) {          any += NumberConversion (ConversionTable, moveBit - FindConversion (ReverseTable, c.ToString ()));        }      }      var cur = any.Length - 1;      for (var n = 0; n < any.Length; n++,cur--) {        var c = any [n].ToString ();        var bitSum = FindConversion (ReverseTable, c) * (int)Math.Pow (tableBit, cur);        sum += bitSum;      }      if (negativeNumber) {        //补位        sum++;        sum = 0 - sum;      }      return sum;    }    static string ConvertToAny (int number, int padSize = 8, string anyString = "0,1,2,3,4,5,6,7,8,9")    {      var conversionPadSize = padSize;      var ConversionTable = BuildConversionTable (anyString);      var ReverseTable = BuildReverseTable (anyString);      long input = Math.Abs ((long)number);      //补码      if (number < 0) {        input -= 1;        conversionPadSize = sizeof(int) * 2;      }            var result = "";      var tableBit = ConversionTable.Count;      while (true) {        if (input >= tableBit) {          result = NumberConversion (ConversionTable, (int)(input % tableBit)) + result;          input = (int)(input / tableBit);        } else {          result = NumberConversion (ConversionTable, (int)input) + result;          break;        }      }      if (result.Length < conversionPadSize) {        //补位        result = result.PadLeft (conversionPadSize, '0');      } //      else {//        //对齐//        if (result.Length % 2 != 0) {//          result = '0' + result;//        }//      }        if (number < 0) {        //反转        var res = result;        result = "";        var moveBit = tableBit - 1;        foreach (var c in res) {          result += NumberConversion (ConversionTable, moveBit - FindConversion (ReverseTable, c.ToString ()));        }      }      return result;    }    static string NumberConversion (Dictionary<int,string> table, int n)    {      return table [n];    }    static int FindConversion (Dictionary<string,int> table, string c)    {      return table [c];    }    static Dictionary<string,int> BuildReverseTable (string tableString)    {      var table = tableString.Split (",".ToCharArray (), StringSplitOptions.RemoveEmptyEntries);      var result = new Dictionary<string,int> ();      for (var i = 0; i < table.Length; i++) {        result.Add (table [i].ToString (), i);      }      return result;    }    static Dictionary<int,string> BuildConversionTable (string tableString)    {      var table = tableString.Split (",".ToCharArray (), StringSplitOptions.RemoveEmptyEntries);      var result = new Dictionary<int,string> ();      for (var i = 0; i < table.Length; i++) {        result.Add (i, table [i].ToString ());      }      return result;    }  }

有趣的测试:

转换结果

 

代码未经测试,自己可以完善