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

本文探讨了在.NET环境下将十六进制字符串高效转换为字节数组的不同方法,并通过实验证明了直接操作字节比使用标准库函数更高效。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求是这样有十六进制字符串要存为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");
        }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值