【问题标题】:Convert Hex To Byte Array in Java gives different results from C#.NET [port from C# to Java]在 Java 中将十六进制转换为字节数组给出了与 C#.NET 不同的结果 [从 C# 移植到 Java]
【发布时间】:2023-03-06 20:41:01
【问题描述】:

我正在尝试将一小段代码从 C# 转换为 Java。 [我想不必说我是菜鸟。 :P]

下面的两个代码返回不同我不明白为什么。感谢您的帮助。

P.S.:我已经检查了问题here,但答案并没有解决我的问题。

C#.NET

public class Test
{
    private static sbyte[] HexToByte(string hex)
        {
            if (hex.Length % 2 == 1)
                throw new Exception("The binary key cannot have an odd number of digits");

            sbyte[] arr = new sbyte[hex.Length >> 1];
            int l = hex.Length;

            for (int i = 0; i < (l >> 1); ++i)
            {
                arr[i] = (sbyte)((GetHexVal(hex[i << 1]) << 4) + (GetHexVal(hex[(i << 1) + 1])));
            }

            return arr;
        }

        private static int GetHexVal(char hex)
        {
            int val = (int)hex;
            return val - (val < 58 ? 48 : 55);
        }
    public static void Main()
    {
        Console.WriteLine(HexToByte("EE")[0]);
    }
}

输出:-18

JAVA

class Test
{
    private static int GetHexVal(char hex)
    {
        int val = (int)hex;
        return val - (val < 58 ? 48 : 55);
    }

    private static byte[] HexToByte(String hex) throws Exception {
        if (hex.length() % 2 == 1)
            throw new Exception("The binary key cannot have an odd number of digits");

        byte[] arr = new byte[hex.length() >> 1];
        int l = hex.length();

        for (int i = 0; i < (l >> 1); ++i)
        {
            arr[i] = (byte)((GetHexVal((char)(hex.charAt(i << 1) << 4)) + (GetHexVal(hex.charAt((i << 1) + 1)))));
        }

        return arr;
    }

    public static void main (String[] args) throws java.lang.Exception
    {
        System.out.println((HexToByte("EE")[0]));
    }
}

输出:39

我不明白为什么会发生这种情况以及克服它的方法是什么?

【问题讨论】:

    标签: java c# hex byte


    【解决方案1】:

    问题在于 Java 代码中第一个字符的括号。这是你的代码:

    GetHexVal((char)(hex.charAt(i << 1) << 4))
    

    这是获取角色,移动它,然后调用GetHexVal。你想改变结果

    // Unnecessary cast removed
    GetHexVal(hex.charAt(i << 1)) << 4
    

    如果您使代码更简单,这将更容易查看。我会写成:

    private static byte[] HexToByte(String hex) {
        if (hex.length() % 2 == 1) {
            throw new IllegalArgumentException("...");
        }
    
        byte[] arr = new byte[hex.length() / 2];
    
        for (int i = 0; i < hex.length(); i += 2)
        {
            int highNybble = parseHex(hex.charAt(i));
            int lowNybble = parseHex(hex.charAt(i + 1));
            arr[i / 2] = (byte) ((highNybble << 4) + lowNybble);
        }
    
        return arr;
    }
    

    虽然位移非常有效,但它的 可读性 不如简单地除以 2...而且将代码拆分为多个语句可以更容易地阅读其中的每个单独部分。

    (我可能会用 switch 语句实现parseHex,也为非十六进制数字抛出IllegalArgumentException...)

    【讨论】:

      猜你喜欢
      • 2013-05-31
      • 2017-07-01
      • 2012-12-01
      • 2020-01-24
      • 2017-06-17
      • 1970-01-01
      • 1970-01-01
      • 2017-03-05
      • 2013-04-07
      相关资源
      最近更新 更多