C#实现62进制字符串压缩16进制字符串(Hex N2M)
借助linxuanchen的一篇文档《C#实现整型数据字任意编码任意进制的转换和逆转换》,实现了使用62进制字符串压缩16进制字符串的功能。主要是在原作者的基础上做了一些转换处理,总结思路如下:1.16进制字符串(0-9A-F)转换成Int64的整数,如:(hex16)DAFDE = (hex10)896734
2. 将Int64整数转换为62进制数(0~9a-zA-Z):3LlA。(linxuanchen的代码已经实现)
需要注意的几个问题:
1.Int64最大的数值为Int64.MaxValue,该常数的值为 9,223,372,036,854,775,807;即十六进制的 0x7FFFFFFFFFFFFFFF。所以实际做字符串压缩的时候,需要对16进制字符串长度进行处理,最多一次压缩15个字符,避免溢出。
2.输出的62进制字符串之间需要用分割符,否则无法解码。
直接代码如下:
using System; using System.Collections.Generic; //using System.Linq; using System.Text; // @ http://www.cnblogs.com/linxuanchen/archive/2012/02/02/2336099.html // @ shadu {AT} foxmail.com namespace HexCover { public class MyString { /// <summary> /// 以MaxLength长度分割strHex16字符串 /// </summary> /// <param name="strHex16"></param> /// <param name="MaxLength"></param> /// <returns></returns> public static List<string> SplitHex16StingWithLength(string strHex16, int MaxLength) { string tmpStr = ""; List<string> StringList = new List<string>(); int count = strHex16.Length / MaxLength; if (strHex16.Length % MaxLength != 0) { for (int i = 0; i <= count; i++) { if ((strHex16.Length - i * MaxLength) > MaxLength) { tmpStr = strHex16.Substring(i * MaxLength, MaxLength); StringList.Add(tmpStr); } else { tmpStr = strHex16.Substring(i * MaxLength, (strHex16.Length % MaxLength)); StringList.Add(tmpStr); } } } else { for (int i = 0; i < count; i++) { tmpStr = strHex16.Substring(i * MaxLength, MaxLength); StringList.Add(tmpStr); } } return StringList; } } public class Number { public string Characters { get; set; } public int Length { get { if (Characters != null) return Characters.Length; else return 0; } } public Number() { Characters = "0123456789"; } public Number(string characters) { Characters = characters; } /// <summary> /// 数字转换为指定的进制形式字符串 /// </summary> /// <param name="number"></param> /// <returns></returns> public string ToString(long number) { List<string> result = new List<string>(); long t = number; while (t > 0) { var mod = t % Length; t = Math.Abs(t / Length); var character = Characters[Convert.ToInt32(mod)].ToString(); result.Insert(0, character); } return string.Join("", result.ToArray()); } /// <summary> /// 指定字符串转换为指定进制的数字形式 /// </summary> /// <param name="str"></param> /// <returns></returns> public long FromString(string str) { long result = 0; int j = 0; char[] arr = str.ToCharArray(); Array.Reverse(arr); //return new string(arr); foreach (char ch in new string(arr)) //foreach (var ch in new string(str.ToCharArray().Reverse().ToArray())) { //Characters.Contains( if (Characters.Contains(ch.ToString())) { result += Characters.IndexOf(ch) * ((long)Math.Pow(Length, j)); j++; } } return result; } } class Program { static void Print(long number, Number adapter) { Console.WriteLine("输入数字:{0}", number); Console.WriteLine("规则:{0}\t\t进制:{1}进制", adapter.Characters, adapter.Length); var numtostr = adapter.ToString(number); Console.WriteLine("转换结果:{0}", numtostr); var strtonum = adapter.FromString(numtostr); Console.WriteLine("逆向转换结果:{0}", strtonum); Console.WriteLine(); Console.WriteLine("============ 无聊的分割线 ============"); Console.WriteLine(); } static void Main(string[] args) { //传统的2进制 Number n1 = new Number("01"); //传统的8进制 Number n2 = new Number("01234567"); //传统的16进制 Number n3 = new Number("0123456789ABCDEF"); //自定义编码的N进制,这个可以用来做验证码? Number n4 = new Number("爹妈说名字太长躲在树后面会被部落发现"); //山寨一个短网址 Number n5 = new Number("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); Print(65535, n1); Print(65535, n2); Print(65535, n3); Print(65535, n4); Print(72057594037927934, n5); Console.ReadKey(); //==== Added by Laien @ 2012-09-25 string strHex = "FFFFFFFFFFFFFFF3131CDAFDE"; string tmpStr = "" ; List<string> strList = MyString.SplitHex16StingWithLength(strHex, 15); foreach (string s in strList) tmpStr += "-" + n5.ToString(Convert.ToInt64(s, 16)); Console.WriteLine("转换前16进制字符串:{0}", strHex); Console.WriteLine("转换后62字符串:{0} (-是分隔符)", tmpStr); Console.ReadKey(); } } }
运行结果如下
补充:软件开发 , C# ,