在 Java 中将十六进制转换为字节数组给出与 C#.NET 不同的结果 [从 C# 移植到 Java]
Convert Hex To Byte Array in Java gives different results from C#.NET [port from C# to Java]
我正在尝试将一小段代码从 C# 转换为 Java。 [我想不必说我是菜鸟。 :P]
下面的两个代码returns不同我不明白为什么。感谢您的帮助。
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]);
}
}
OUTPUT: -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]));
}
}
OUTPUT: 39
我不明白为什么会这样,有什么办法可以克服?
问题出在 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;
}
虽然移位非常高效,但它远不如简单地除以二那样可读...并且将代码拆分成多个语句使得每个人更容易阅读一部分。
(我可能会用 switch 语句实现 parseHex
,也为非十六进制数字抛出 IllegalArgumentException
...)
我正在尝试将一小段代码从 C# 转换为 Java。 [我想不必说我是菜鸟。 :P]
下面的两个代码returns不同我不明白为什么。感谢您的帮助。
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]);
}
}
OUTPUT: -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]));
}
}
OUTPUT: 39
我不明白为什么会这样,有什么办法可以克服?
问题出在 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;
}
虽然移位非常高效,但它远不如简单地除以二那样可读...并且将代码拆分成多个语句使得每个人更容易阅读一部分。
(我可能会用 switch 语句实现 parseHex
,也为非十六进制数字抛出 IllegalArgumentException
...)