简体   繁体   English

在C#中转换int-> hex-> binary时出现错误“十六进制字符串的位数为奇数”

[英]Error “Hex string have a odd number of digits” while converting int->hex->binary in C#

Aim : 目标 :

To convert a integer value first to hexstring and then to byte[]. 首先将整数值转换为十六进制字符串,然后转换为byte []。

Example : 范例:

   Need to convert  int:1024 to hexstring:400 to byte[]: 00000100 00000000

Method: 方法:

For converting from integer to hex string i tried below code 为了从整数转换为十六进制字符串,我尝试了以下代码

    int i=1024;
    string hexString = i.ToString("X");

i got hexstring value as "400". 我得到的十六进制值为“ 400”。 Then i tried converting hex string to byte[] using below code 然后我尝试使用以下代码将十六进制字符串转换为byte []

    byte[] value = HexStringToByteArray(hexValue);

    /* function for converting hexstring to  byte array */
    public  byte[] HexStringToByteArray(string hex)
    {

        int NumberChars = hex.Length;

        if(NumberChars %2==1)
          throw new Exception("Hex string cannot have an odd number of digits.");

        byte[] bytes = new byte[NumberChars / 2];
        for (int i = 0; i < NumberChars; i += 2)
            bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
        return bytes;

    }

Error: 错误:

Here i got the exception "Hex String cannot have a odd number of digits" 在这里我得到了一个例外“十六进制字符串不能有奇数个数字”

Solution : ?? 解决方案

您可以强制ToString返回特定数目的数字:

string hexString = i.ToString("X08");

Your code throws the exception you're seeing: 您的代码将引发您所看到的异常:

throw new Exception("Hex string cannot have an odd number of digits.");

You can improve the conversion method to also accept odd hex string lengths like this: 您可以改进转换方法,以接受如下所示的奇数十六进制字符串长度:

using System.Collections.Generic;
using System.Linq;

// ...

public  byte[] HexStringToByteArray(string hex)
    {
        var result = new List<byte>();

        for (int i = hex.Length - 1; i >= 0; i -= 2)
            {
                if (i > 0)
                    {
                        result.Insert(0, Convert.ToByte(hex.Substring(i - 1, 2), 16));
                    }
                else
                    {
                        result.Insert(0, Convert.ToByte(hex.Substring(i, 1), 16));
                    }
            }

        return bytes.ToArray();
    }

This code should iterate through the hex string from its end, adding new bytes to the beginning of the resulting list (that will be transformed into an array before returning the value). 此代码应从其末尾遍历十六进制字符串,并将新的字节添加到结果列表的开头(在返回值之前,该列表将转换为数组)。 If a single digit remains, it will be treated separately. 如果仅剩一位数字,则将单独处理。

The exception is thrown by your own code. 异常是由您自己的代码引发的。 You can make your code more flexible to accept hex strings that have an odd number of digits: 您可以使代码更加灵活,以接受具有奇数位数的十六进制字符串:

if (hex.Length % 2 == 1) hex = "0"+hex;

Now you can remove the odd/even check, and your code will be alright. 现在,您可以删除奇/偶校验,代码也就可以了。

Your hex string has an odd number of digits and you are explicitly checking for that and throwing the exception. 您的十六进制字符串的位数为奇数,并且您正在明确地检查该位数并引发异常。 You need to decide why you put this line of code in there and whether you need to remove that in favour of other logic. 您需要确定为什么将这行代码放入其中,以及是否需要删除该行以便使用其他逻辑。

Other options are: 其他选项是:

  1. add a "0" to the beginning of the string to make it even length 在字符串的开头添加“ 0”以使其长度均匀
  2. force whoever is calling that code to always provide an even length string 强制调用该代码的人始终提供均匀长度的字符串
  3. change the later code to deal with odd numbers of characters properly... 更改后面的代码以正确处理奇数个字符...

In comments you have suggested that the first is what you need to know in which case: 在注释中,您建议第一种情况是您需要了解的情况:

if(hex.Length%2==1)
    hex = "0"+hex;

Put this at the beginning of your method and if you get an odd number in then you will add the zero to it automatically. 将其放在方法的开头,如果输入的是奇数,则将自动添加零。 You can of course then take out your later check and exception throw. 当然,您可以随后取出以后的检查和异常抛出。

Of note is that you may want to validate the input string as hex or possibly just put a try catch round the conversion to make sure that it is a valid hex string. 值得注意的是,您可能想将输入字符串验证为十六进制,或者可能只是尝试绕过转换以确保它是有效的十六进制字符串。

Also since it isn't clear whether the string is a necessary intermediate step or just one that you think is necessary, you might be interested in C# int to byte[] which deals with converting to bytes without the intermediate string. 另外,由于不清楚该字符串是必需的中间步骤还是只是您认为必要的步骤,因此您可能会对C#int to byte []感兴趣,该方法处理不带中间字符串的字节转换。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM