当前位置:编程学习 > C#/ASP.NET >>

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# ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,