C#字符串、字符串數組、字節、字節數組和16進制,8進制,2進制相互轉換 及數字和ASCII碼互轉


最近做硬件物聯網IOT、MQTT、TCPIP網絡編程,經常被各種進制和字符串之間的轉換弄的頭疼,麻蛋的,索性抄襲幾篇博客,合兵一處,整理如下:

 

不知道何時開始,很多程序員喜歡用ToLower,ToUpper去實現忽略大小寫模式的字符串相等性比較,有可能這個習慣是從別的語言引進的,大膽猜測下是JS,為了不引起爭論,我指的JS是技師的意思~

一:背景

1. 講故事

在我們一個訂單聚合系統中,每一筆訂單都會標注來源,比如JD,Taobao,Etao,Shopex 等等一些渠道,UI上也提供高級配置輸入自定義的訂單來源,后來客戶反饋輸入xxx查詢不出訂單,這里就拿shopex為例,用戶用小寫的shopex查詢,但系統中標注的是首字母大寫的Shopex,所以自然無法匹配,為了解決這個問題開發小哥就統一轉成大寫做比對,用代碼表示如下:


                var orderfrom = "shopex".ToUpper(); customerIDList = MemoryOrders.Where(i =>i.OrderFrom.ToUpper()==orderFrom) .Select(i => i.CustomerId).ToList(); 

改完后就是這么牛的上線了,乍一看也沒啥問題,結果一查詢明顯感覺比之前速度慢了好幾秒,干脆多點幾下,好咯。。。在監控中發現CPU和memory突高突低,異常波動,這位小哥又在寫bug了,查了下代碼問他為什么這么寫,小哥說在js中就是這么比較的~~~

2. string.Compare 改造

其實在C#中面對忽略大小寫形式的比較是有專門的方法,性能高而且還不費內存,它就是 string.Compare,所以把上面代碼改成如下就可以了。


                var orderfrom = "shopex"; customerIDList = MemoryOrders.Where(string.Compare(i.TradeFrom, tradefrom, StringComparison.OrdinalIgnoreCase) == 0) .Select(i => i.CustomerId).ToList(); 

這其中的 StringComparison.OrdinalIgnoreCase枚舉就是用來忽略大小寫的,上線之后除了CPU還是有點波動,其他都沒有問題了。

1.請問c#中如何將十進制數的字符串轉化成十六進制數的字符串

//十進制轉二進制
Console.WriteLine("十進制166的二進制表示: "+Convert.ToString(166, 2));
//十進制轉八進制
Console.WriteLine("十進制166的八進制表示: "+Convert.ToString(166, 8));
//十進制轉十六進制
Console.WriteLine("十進制166的十六進制表示: "+Convert.ToString(166, 16));
    
//二進制轉十進制
Console.WriteLine("二進制 111101 的十進制表示: "+Convert.ToInt32("111101", 2));
//八進制轉十進制
Console.WriteLine("八進制 44 的十進制表示: "+Convert.ToInt32("44", 8));
//十六進制轉十進制
Console.WriteLine("十六進制 CC的十進制表示: "+Convert.ToInt32("CC", 16));

 

2.在串口通訊過程中,經常要用到 16進制與字符串、字節數組之間的轉換

private string StringToHexString(string s,Encoding encode)
        {
            byte[] b = encode.GetBytes(s);//按照指定編碼將string編程字節數組
            string result = string.Empty;
            for (int i = 0; i < b.Length; i++)//逐字節變為16進制字符,以%隔開
            {
                result += "%"+Convert.ToString(b[i], 16);
            }
            return result;
        }
        private string HexStringToString(string hs, Encoding encode)
        {
            //以%分割字符串,並去掉空字符
            string[] chars = hs.Split(new char[]{'%'},StringSplitOptions.RemoveEmptyEntries);
            byte[] b = new byte[chars.Length];
            //逐個字符變為16進制字節數據
            for (int i = 0; i < chars.Length; i++)
            {
                b[i] = Convert.ToByte(chars[i], 16);
            }
            //按照指定編碼將字節數組變為字符串
            return encode.GetString(b);
        }

 


        /// <summary>
        /// 字符串轉16進制字節數組
        /// </summary>
       /// <param name="hexString"></param>
        /// <returns></returns>
        private static byte[] strToToHexByte(string hexString)
        {
             hexString = hexString.Replace(" ", "");
           if ((hexString.Length % 2) != 0)
                 hexString += " ";
            byte[] returnBytes = new byte[hexString.Length / 2];
            for (int i = 0; i < returnBytes.Length; i++)
                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
            return returnBytes;
         }
 

 


/// <summary>
        /// 字節數組轉16進制字符串
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static string byteToHexStr(byte[] bytes)
       {
            string returnStr = "";
            if (bytes != null)
            {
                for (int i = 0; i < bytes.Length; i++)
                {
                     returnStr += bytes[i].ToString("X2");
                 }
             }
            return returnStr;
         }
 

 


/// <summary>
        /// 從漢字轉換到16進制
        /// </summary>
        /// <param name="s"></param>
        /// <param name="charset">編碼,如"utf-8","gb2312"</param>
        /// <param name="fenge">是否每字符用逗號分隔</param>
       /// <returns></returns>
        public static string ToHex(string s, string charset, bool fenge)
        {
            if ((s.Length % 2) != 0)
            {
                 s += " ";//空格
                //throw new ArgumentException("s is not valid chinese string!");
             }
             System.Text.Encoding chs = System.Text.Encoding.GetEncoding(charset);
            byte[] bytes = chs.GetBytes(s);
            string str = "";
            for (int i = 0; i < bytes.Length; i++)
            {
                str += string.Format("{0:X}", bytes[i]);
                if (fenge && (i != bytes.Length - 1))
                {
                     str += string.Format("{0}", ",");
                 }
             }
            return str.ToLower();
         }
 

 


///<summary>
        /// 從16進制轉換成漢字
        /// </summary>
        /// <param name="hex"></param>
        /// <param name="charset">編碼,如"utf-8","gb2312"</param>
       /// <returns></returns>
        public static string UnHex(string hex, string charset)
        {
           if (hex == null)
                throw new ArgumentNullException("hex");
             hex = hex.Replace(",", "");
             hex = hex.Replace("\n", "");
             hex = hex.Replace("\\", "");
             hex = hex.Replace(" ", "");
            if (hex.Length % 2 != 0)
            {
                 hex += "20";//空格
             }
            // 需要將 hex 轉換成 byte 數組。 
            byte[] bytes = new byte[hex.Length / 2];

           for (int i = 0; i < bytes.Length; i++)
            {
                try
                {
                    // 每兩個字符是一個 byte。 
                     bytes[i] = byte.Parse(hex.Substring(i * 2, 2),
                     System.Globalization.NumberStyles.HexNumber);
                 }
                catch
                {
                    // Rethrow an exception with custom message. 
                    throw new ArgumentException("hex is not a valid hex number!", "hex");
                 }
             }
             System.Text.Encoding chs = System.Text.Encoding.GetEncoding(charset);
            return chs.GetString(bytes);
         }

1.字符串=>比特數組

(1)byte[] bt=System.Text.Encoding.Default.GetBytes("字符串");

(2)byte[] bt=Convert.FromBase64String("字符串");

補充:

System.Text.Encoding.Unicode.GetBytes(str);
System.Text.Encoding.UTF8.GetBytes(str);
System.Text.Encoding.GetEncoding("gb2312").GetBytes(str); //指定編碼方式
string str = "中國?ss123?";
byte[] bytes = System.Text.Encoding.Default.GetBytes(str); //gb2312編碼 漢字占2個字節、英文字母占1個字節 bytes長度為12
string s = System.Text.Encoding.Default.GetString(new byte[] { bytes[0],bytes[1] });//解碼后為“中”
byte[] bytes = {97, 98, 99, 100, 101, 102};  
string str = System.Text.Encoding.ASCII.GetString(bytes); //結果為:abcdef  ASCII碼表

      常用方法:

復制代碼
復制代碼
GetString  已重載。 在派生類中重寫時,將一個字節序列解碼為一個字符串。
GetChars   已重載。 在派生類中重寫時,將一個字節序列解碼為一組字符。
GetBytes   已重載。 在派生類中重寫時,將一組字符編碼為一個字節序列。

GetByteCount  已重載。 在派生類中重寫時,計算對一組字符進行編碼所產生的字節數。
GetCharCount  已重載。 在派生類中被重寫時,計算對字節序列進行解碼所產生的字符數。

GetDecoder 在派生類中重寫時,獲取一個解碼器,該解碼器將已編碼的字節序列轉換為字符序列。
GetEncoder 在派生類中重寫時,獲取一個解碼器,該解碼器將Unicode字符序列轉換為已編碼的字節序列
復制代碼
復制代碼

 

2.比特數組=>字符串

(1)string str=System.Text.Encoding.Default.GetString(bt);

(2)string str=Convert.ToBase64String(bt);

 

3.字符串=>

(1)MemoryStream ms=new MemoryStream(System.Text.Encoding.Default.GetBytes("字符串"));

(2)MemoryStream ms=new MemoryStream(Convert.FromBase64String("字符串"));

 

4.流=>字符串

(1)string str=Convert.ToBase64String(ms.ToArray());

(2)string str=System.Text.Encoding.Default.GetString(ms.ToArray());

 

5.比特數組=>

(1)MemoryStream ms=new MemoryStream(bt);

(2)MemoryStream ms=new MemoryStream();ms.Read(bt,0,bt.Lenght);

 

6.流=>比特數組

(1)byte[] bt=ms.ToArray();

(2)MemoryStream ms=new MemoryStream();ms.Write(bt,0,ms.Length);

7、ASCII碼<-------->數字互轉

//ASCII碼轉字符:

public static int Asc(string character)
   {
    if (character.Length == 1)
    {
     System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
     int intAsciiCode = (int)asciiEncoding.GetBytes(character)[0];
     return (intAsciiCode);
    }
    else
    {
     throw new Exception("Character is not valid.");
    }


   }


//數字轉ASCII碼轉字符:


public static string Chr(int asciiCode)
   {
    if (asciiCode >= 0 && asciiCode <= 255)
    {
     System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
     byte[] byteArray = new byte[] { (byte)asciiCode };
     string strCharacter = asciiEncoding.GetString(byteArray);
     return (strCharacter);
    }
    else
    {
     throw new Exception("ASCII Code is not valid.");
    }


}

 實戰,解析如下字符串:

0x78,0x32,0x61,0x61,0x30,0x32,0x30,0x30,0x39,0x30,0x37,0x30,0x30,0x30,0x30,0x31,0x02,0x58,0x00,0xC8,0x02,0x74,0x00,0x00,0x4E,0x39,0x00,0x00,0x00,0x01,0x1D,0x00,0x02,0x00,0x61,0x0C,0xF0,0x0C,0xEC,0x44,0x44,0x13,0x0C,0xEC,0x0C,0xED,0x0C,0xED,0x0C,0xED,0x0C,0xEC,0x0C,0xEC,0x0C,0xF0,0x0C,0xEF,0x0C,0xEC,0x0C,0xEF,0x0C,0xEF,0x0C,0xEF,0x0C,0xEE,0x0C,0xEE,0x0C,0xEE,0x0C,0xEF,0x0C,0xEE,0x0C,0xEE,0x0C,0xED,0x02,0x44,0x44,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
    public class btinfoModel
    {
        public  Dictionary<string, int> Dic = new Dictionary<string, int>();
        public btinfoModel() { }
        public btinfoModel(string btinfo)
        {
            if (string.IsNullOrEmpty(btinfo))
            {
                return;
            }
            var By48 = btinfo.Replace("0x", "");
            var ByAry = By48.Split(',').ToList();
            List<int> lst = new List<int>();

            foreach (var item in ByAry)
            {
                var No = Convert.ToInt32(item, 16);
                lst.Add(No);
                //Console.WriteLine("數值為:" + No);
            }

            Dictionary<string, int> Dic = new Dictionary<string, int>();
            Dic.Add("BettaryNum", 16);//電池編號
            Dic.Add("Voltage", 2);//電池電壓
            Dic.Add("Caption", 2);//電池容量
            Dic.Add("TotalVoltage", 2);//總電壓
            Dic.Add("Electric", 2);//電流
            Dic.Add("BettaryStatus", 1);//電池狀態
            Dic.Add("SOC", 1);//soc 電量
            Dic.Add("MOS", 1);//MOS狀態
            Dic.Add("ljfdrl", 2);//累計放電容量
            Dic.Add("ljcdrl", 2);//累計充電容量
            Dic.Add("softVersion", 2);//軟件版本號
            Dic.Add("heardWareVersion", 2);//硬件版本號
            Dic.Add("MaxSigVoltage", 2);//最大單體電壓
            Dic.Add("MinSigVoltage", 2);//最小單體電壓
            Dic.Add("MaxTemperature", 1);//最大溫度
            Dic.Add("MinTemperature", 1);//最小溫度

            var SkipVoltageNum = 0;
            foreach (var item in Dic)
            {
                SkipVoltageNum += item.Value;
            }
            Dic.Add("VoltageNum", 1);//電壓個數
            var VoltageNum = lst.Skip(SkipVoltageNum).Take(1).ToList()[0];
            Dic.Add("SigVoltage", VoltageNum * 2);//單體電壓
            var SkipTemperature = 0;
            foreach (var item in Dic)
            {
                SkipTemperature += item.Value;
            }
            Dic.Add("TemperatureNum", 1);//溫度個數
            var TemperatureNum = lst.Skip(SkipTemperature).Take(1).ToList()[0];
            Dic.Add("SigTemperature", TemperatureNum * 1);//單體溫度
            Dic.Add("Mos_1", 1);//Mos_1
            Dic.Add("Mos_2", 1);//Mos_2
            Dic.Add("Police", 2);//報警
            Dic.Add("ljqcbcs", 2);//連接器插拔次數
            Dic.Add("ljcdcs", 2);//累計充電次數
            Dic.Add("cdqcdcs", 2);//充電器充電次數
            Dic.Add("dgcdcs", 2);//電櫃充電次數
            Dic.Add("ggStatus", 1);//觀感狀態

            //var TotalLength = 0;
            //foreach (var item in Dic)
            //{
            //    TotalLength += item.Value;
            //}
            int TotalNum = 0;
            foreach (var item in Dic)
            {
                var result = lst.Skip(TotalNum).Take(item.Value).ToList();
                TotalNum += item.Value;
                switch (item.Key)
                {
                    case "BettaryNum": this.BettaryNum = GetAsciiByIntAry(result); break;
                    case "Voltage": this.Voltage = GetValue(result); break;
                    case "Caption": this.Caption = GetValue(result); break;
                    case "TotalVoltage": this.TotalVoltage = GetValue(result); break;
                    case "Electric": this.Electric = GetValue(result); break;
                    case "BettaryStatus": this.BettaryStatus = GetValue(result); break;
                    case "SOC": this.SOC = GetValue(result); break;
                    case "MOS": this.MOS = GetValue(result); break;
                    case "ljfdrl": this.ljfdrl = GetValue(result); break;
                    case "ljcdrl": this.ljcdrl = GetValue(result); break;
                    case "softVersion": this.softVersion = GetValue(result); break;
                    case "heardWareVersion": this.heardWareVersion = GetValue(result); break;
                    case "MaxSigVoltage": this.MaxSigVoltage = GetValue(result); break;
                    case "MinSigVoltage": this.MinSigVoltage = GetValue(result); break;
                    case "MaxTemperature": this.MaxTemperature = GetValue(result)-40; break;
                    case "MinTemperature": this.MinTemperature = GetValue(result)-40; break;
                    case "VoltageNum": this.VoltageNum = GetValue(result); break;
                    case "SigVoltage": this.SigVoltage = string.Join(",", GetSigVoltageValue(result)); break;
                    case "TemperatureNum": this.TemperatureNum = GetValue(result); break;
                    case "SigTemperature": this.SigTemperature = GetSigTemperature(result); break;
                    case "Mos_1": this.Mos_1 = GetValue(result)-40; break;
                    case "Mos_2": this.Mos_2 = GetValue(result)-40; break;
                    case "Police": this.Police = GetValue(result); break;
                    case "ljqcbcs": this.ljqcbcs = GetValue(result); break;
                    case "ljcdcs": this.ljcdcs = GetValue(result); break;
                    case "cdqcdcs": this.cdqcdcs = GetValue(result); break;
                    case "dgcdcs": this.dgcdcs = GetValue(result); break;
                    case "ggStatus": this.ggStatus = GetValue(result); break;
                }
            }

        }

        public string BettaryNum { get; set; } //電池串號 16位
        public int Voltage { get; set; } //電池電壓
        public int Caption { get; set; } //電池容量
        public int TotalVoltage { get; set; } //總電壓
        public int Electric { get; set; } //電流
        public int BettaryStatus { get; set; } //電池狀態
        public string BettaryStatusString { get { return GetBattaryStatus(BettaryStatus); } } //電池狀態
        public int SOC { get; set; } //soc 電量
        public int MOS { get; set; } //MOS狀態
        public string MOSEjz { get { return GetEjzByInt(MOS, 8); } } //MOS狀態 二進制
        public string MOSEjzString { get { return GetMosEjzString(MOSEjz); } }  //MOS狀態 中文
        public int ljfdrl { get; set; } //累計放電容量
        public int ljcdrl { get; set; } //累計充電容量
        public int softVersion { get; set; } //軟件版本號
        public int heardWareVersion { get; set; } //硬件版本號
        public int MaxSigVoltage { get; set; } //最大單體電壓
        public int MinSigVoltage { get; set; } //最小單體電壓
        public int MaxTemperature { get; set; } //最大溫度
        public int MinTemperature { get; set; } //最小溫度
        public int VoltageNum { get; set; } //電壓個數
        public string SigVoltage { get; set; } //單體電壓 = 電壓個數*2
        public int TemperatureNum { get; set; } //溫度個數
        public string SigTemperature { get; set; } //單體溫度 =溫度個數*1
        public int Mos_1 { get; set; } //Mos_1
        public int Mos_2 { get; set; } //Mos_2
        public int Police { get; set; } //報警
        public string PoliceEjz { get { return GetEjzByInt(Police); } }//報警二進制
        public string PoliceEjzString { get { return GetEjzString(PoliceEjz); } }//報警二進制對應的報警值 中文
        public int ljqcbcs { get; set; } //連接器插拔次數
        public int ljcdcs { get; set; } //累計充電次數
        public int cdqcdcs { get; set; } //充電器充電次數
        public int dgcdcs { get; set; } //電櫃充電次數
        public int ggStatus { get; set; } //觀感狀態

        #region 方法集
        /// <summary>
        /// 獲取電池狀態
        /// </summary>
        /// <param name="sb"></param>
        /// <returns></returns>
        private string GetBattaryStatus(int sb)
        {
            var result = GetAsciiByInt(sb);
            if (result == "C")
            {
                return "充電";
            }
            else if (result == "D")
            {
                return "放電";
            }
            else if (result == "N")
            {
                return "靜止";
            }
            return "暫無電池狀態";
        }
        /// <summary>
        /// 獲取電池串號
        /// </summary>
        /// <param name="Ary"></param>
        /// <returns></returns>
        private string GetAsciiByIntAry(List<int> Ary)
        {
            string result = string.Empty;
            foreach (var item in Ary)
            {
                result += GetAsciiByInt(item);
            }
            return result;
        }
        /// <summary>
        /// 根據數字獲取ASCII碼
        /// </summary>
        /// <param name="num"></param>
        /// <returns></returns>
        private string GetAsciiByInt(int asciiCode)
        {
            if (asciiCode >= 0 && asciiCode <= 255)
            {
                System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
                byte[] byteArray = new byte[] { (byte)asciiCode };
                string strCharacter = asciiEncoding.GetString(byteArray);
                return (strCharacter);
            }
            else
            {
                throw new Exception("ASCII Code is not valid.");
            }
        }

        /// <summary>
        /// 16進制轉十進制 具體參考十六進制的數值
        /// </summary>
        /// <param name="Ary"></param>
        /// <returns></returns>
        private  int GetValue(List<int> Ary)
        {
            double result = 0;
            var cm = 0;
            cm = Ary.Count;
            foreach (var item in Ary)
            {
                if (cm - 1 == 0)
                {
                    result += item;
                }
                else
                {
                    result += item * Math.Pow(16, (cm * 2 - 2));
                    cm--;
                }

            }
            return Convert.ToInt32(result);
        }

        /// <summary>
        /// 計算單體電壓 單體電壓占2字節,因此需要兩字節合兵一起計算
        /// </summary>
        /// <param name="Ary"></param>
        /// <returns></returns>
        private List<int> GetSigVoltageValue(List<int> SigVoltage)
        {
            List<int> AeryList = new List<int>();
            var cc = SigVoltage.Count;
            for(int i = 0; i < cc / 2; i++)
            {
                var Aery = SigVoltage.Skip(i * 2).Take(2).ToList();
                var result = GetValue(Aery);
                AeryList.Add(result);
            }
            return AeryList;
        }

        private string GetSigTemperature(List<int> Ary)
        {
            List<int> result = new List<int>();
            foreach (var item in Ary)
            {
                var citem = item - 40;
                result.Add(citem);
            }
            return string.Join(",", result.ToArray());
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="Number">數字</param>
        /// <param name="bitNum">位數 16位沾二字節 8位占一字節</param>
        /// <returns></returns>
        private string GetEjzByInt(int Number,int bitNum=16)
        {
            var result = Convert.ToString((ushort)Number, 2);
            var len = result.Length;
            if (len < 16)
            {
                for (int i = 0; i < bitNum - len; i++)
                {
                    result = "0" + result;
                }
            }
            return result;
        }

        /// <summary>
        /// 根據二進制 獲取報警值
        /// 0000000000000011  數字3  從右至左移位  非別為0到15位
        /// </summary>
        /// <param name="ejz"></param>
        /// <returns></returns>
        private string GetEjzString(string ejz)
        {
            string result = string.Empty;
            var charAry = ejz.ToCharArray();
            foreach (var item in charAry)
            {
                if (item.ToString() == "1")
                {
                    switch (charAry.ToList().IndexOf(item))
                    {
                        case 0: result+="MOS溫度高_"; break;
                        case 1: result+= "短路_"; break;
                        case 2: result+= "放電低溫_"; break;
                        case 3: result+= "放電高溫_"; break;
                        case 4: result+= "充電低溫_"; break;
                        case 5: result+= "充電高溫_"; break;
                        case 6: result+=""; break;
                        case 7: result+=""; break;
                        case 8: result+= "SOC低_"; break;
                        case 9: result+= "充電過流_"; break;
                        case 10: result+= "放電過流_"; break;
                        case 11: result+=""; break;
                        case 12: result+=""; break;
                        case 13: result+= "單體欠壓_"; break;
                        case 14: result+= "單體過壓_"; break;
                        case 15: result+= "盲充過流_"; break;
                    }
                }
            }
            return result;
        }

        private string GetMosEjzString(string ejz)
        {
            string result = string.Empty;
            var charAry = ejz.ToCharArray();
            foreach (var item in charAry)
            {
                if (item.ToString() == "1")
                {
                    switch (charAry.ToList().IndexOf(item))
                    {
                        case 0: result += ""; break;
                        case 1: result += ""; break;
                        case 2: result += ""; break;
                        case 3: result += ""; break;
                        case 4: result += ""; break;
                        case 5: result += ""; break;
                        case 6: result += "放電"; break;
                        case 7: result += "充電"; break;
                      
                    }
                }
            }
            return result;
        }
        #endregion
    }
View Code

 結果:

@天才卧龍的博客


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM