将十六进制字符串转为byte数组

需求是这样有十六进制字符串要存为byte数组

如string st = "0A000000",转为byte后为 byte[0]=10,byte[1]=0,byte[2]=0,byte[3]=0   

因.net2.0可用Convert将十六进制字符串转为byte有现成的就用吧。代码如下:

         public   static   byte [] writebytes1( string  sBytes)
        
{
            Stopwatch watch 
= new Stopwatch();
            watch.Reset();
            watch.Start();
            Debug.Assert(sBytes.Length 
% 2 == 0"数组长度错");

            
int pos = 0;
            
int len = (sBytes.Length / 2);
            
byte[] b = new byte[len];
            
int count = sBytes.Length;

            
for (int i = 0; i < count; i += 2)
            
{
                b[pos] 
= Convert.ToByte(sBytes.Substring(i, 2), 16);
                pos
++;
            }

            watch.Stop();
            Console.WriteLine(
"{0}:{1}""writebytes1", watch.Elapsed);
            
return b;
        }

但我觉得不够快,且发现我传的字符串长度都是8的整数倍,于是就用Convert.ToInt32以8位长度来转成uint32的数字再用BitConverter转为byte数组,但转换后数组内容与我的要求内容位置相返,所以再用Array.Reverse(Array)方法将数组返转,改了代码如下:

         public   static   byte [] writebytes2( string  sBytes)
        
{
            Stopwatch watch 
= new Stopwatch();
            watch.Reset();
            watch.Start();

            Debug.Assert(sBytes.Length 
% 2 == 0"数组长度错");
            Debug.Assert(sBytes.Length 
% 8 == 0"数组长度不适合用于此方法");

            
int pos = 0;
            
int len = (sBytes.Length / 2);
            
byte[] b = new byte[len];
            
int count = sBytes.Length;

      
byte[] bt;
            
for (int i = 0; i < count; i += 8)
            
{
                bt 
= BitConverter.GetBytes(Convert.ToInt32(sBytes.Substring(i, 8), 16));
                Array.Reverse(bt);
                bt.CopyTo(b, pos);
                pos 
+= 4;
            }


            watch.Stop();
            Console.WriteLine(
"{0}:{1}""writebytes2", watch.Elapsed);
            
return b;
        }

测了一下没快多少,而且字符串加长后反而更慢,马上用Reflector看了一下发现是Array.Reverse的实现方法把速度拖下来了,没办法只能自已写整型转byte的方法不用BitConverter和Array.Reverse。代码如下:

  public   static   byte [] writebytes3( string  sBytes)
        
{
            Stopwatch watch 
= new Stopwatch();
            watch.Reset();
            watch.Start();

            Debug.Assert(sBytes.Length 
% 2 == 0"数组长度错");
            Debug.Assert(sBytes.Length 
% 8 == 0"数组长度不适合用于此方法");

            
int pos = 0;
            
int len = (sBytes.Length / 2);
            
byte[] b = new byte[len];
            
int count = sBytes.Length;

            
for (int i = 0; i < count; i += 8)
            
{
                
ulong ui = Convert.ToUInt32(sBytes.Substring(i, 8), 16);
                b[pos] 
= (byte)((ui & 0xFF000000>> 24);
                b[pos 
+ 1= (byte)((ui & 0x00FF0000>> 16);
                b[pos 
+ 2= (byte)((ui & 0x0000FF00>> 8);
                b[pos 
+ 3= (byte)((ui & 0x000000FF));

                pos 
+= 4;
            }


            watch.Stop();
            Console.WriteLine(
"{0}:{1}""writebytes3", watch.Elapsed);
            
return b;
        }

测试了一下第三种方法只用了前两种大约1/3的时间。(奇怪的是后来我又用ToUInt64取64位来写同样的方法,却反而比用ToUInt32实现的方法慢,可惜无法了解底层API是如何实现Convert.ToUInt64,还请了解的能给我说说)

         static   void  Main( string [] args)
        {
            
string  st  =   " 1E041800050013000022A322232C2323303B5C2D22A322232C232330 "
              
+   " 1E041D00060018000022A322232C2323303B5B5265645D5C2D22A322232C232330 "
              
+   " 1E041E00070019000022A322232C2323302E30303B5C2D22A322232C2323302E3030 "
              
+   " 1E04230008001E000022A322232C2323302E30303B5B5265645D5C2D22A322232C2323302E3030 "
+   " 1E0435002A003000005F2D22A3222A20232C2323305F2D3B5C2D22A3222A20232C2323305F2D3B5F2D22A3222A20222D225F2D3B5F2D405F2D "
+   " 1E042C0029002700005F2D2A20232C2323305F2D3B5C2D2A20232C2323305F2D3B5F2D2A20222D225F2D3B5F2D405F2D "   +   " 1E043D002C003800005F2D22A3222A20232C2323302E30305F2D3B5C2D22A3222A20232C2323302E30305F2D3B5F2D22A3222A20222D223F3F5F2D3B5F2D405F2D "
+   " 1E0434002B002F00005F2D2A20232C2323302E30305F2D3B5C2D2A20232C2323302E30305F2D3B5F2D2A20222D223F3F5F2D3B5F2D405F2D " ;

            
byte [] bt1  =  writebytes1(st);
            
byte [] bt2  =  writebytes2(st);
            
byte [] bt3  =  writebytes3(st);

            
for  ( int  i  =   0 ; i  <  bt1.Length; i ++ )
            {
                
if  (bt1[i]  !=  bt2[i]  ||  bt1[i]  !=  bt3[i] ) 
                {
                    Console.WriteLine(
" err " );
                    
return ;
                }
            }
            Console.WriteLine(
" ok " );
        }

 

你可能感兴趣的:(将十六进制字符串转为byte数组)