C#和Java中的十六进制到字节数组给出了不同的结果

C#和Java中的十六进制到字节数组给出了不同的结果,c#,java,hex,byte,bytearray,C#,Java,Hex,Byte,Bytearray,首先,为这篇长文章感到抱歉,我想包括我所有的想法,这样你们就更容易找到我代码的错误 我想将十六进制字符串从C#应用程序传输到Java应用程序。但是,当我在两种语言上将相同的十六进制值转换为字节数组时,输出是不同的 例如,相同的十六进制值给出 [101, 247, 11, 173, 46, 74, 56, 137, 185, 38, 40, 191, 204, 104, 83, 154] 在C#和 在爪哇 以下是我在C#中使用的方法: 还有一个Java示例: String hexSt

首先,为这篇长文章感到抱歉,我想包括我所有的想法,这样你们就更容易找到我代码的错误

我想将十六进制字符串从C#应用程序传输到Java应用程序。但是,当我在两种语言上将相同的十六进制值转换为字节数组时,输出是不同的

例如,相同的十六进制值给出

  [101, 247, 11, 173, 46, 74, 56, 137, 185, 38, 40, 191, 204, 104, 83, 154]
在C#和

在爪哇

以下是我在C#中使用的方法:

还有一个Java示例:

    String hexString = "65F70BAD2E4A3889B92628BFCC68539A";
    byte[] byteArray = HexBytes.HexStringToByteArray(hexString);
    //Using the debugger, byteArray = [101, -9, 11, -83, 46, 74, 56, -119, -71, 38, 40, -65, -52, 104, 83, -102]
    String hexString2 = HexBytes.ByteArrayToHexString(byteArray);
    System.out.println("HEX: " + hexString2);
    //Outputs 65F70BAD2E4A3889B92628BFCC68539A
正如您所看到的,当我执行相反的操作时,最后的十六进制值等于第一个,这意味着我转换的方式可能在两种语言中都很好。但是我不明白为什么从十六进制到字节数组的转换在两种语言中是不同的。我以为十六进制只是另一个基数上的数字

谢谢你的帮助

西德里克

更新

我修复了这个问题,用以下代码替换了C代码:

public static string ByteArrayToHexString(sbyte[] byteArray)
{
    return BitConverter.ToString(convert(byteArray)).Replace("-", ""); //To convert the whole array
}

public static sbyte[] HexStringToByteArray(string hexString)
{

    byte[] HexAsBytes = new byte[hexString.Length / 2];
    for (int index = 0; index < HexAsBytes.Length; index++)
    {
        string byteValue = hexString.Substring(index * 2, 2);
        HexAsBytes[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
    }

    return convert(HexAsBytes);
}


private static sbyte[] convert(byte[] byteArray)
{
    sbyte[] sbyteArray = new sbyte[byteArray.Length];
    for (int i = 0; i < sbyteArray.Length; i++)
    {
        sbyteArray[i] = unchecked((sbyte) byteArray[i]);
    }

    return sbyteArray;
}

private static byte[] convert(sbyte[] sbyteArray)
{
    byte[] byteArray = new byte[sbyteArray.Length];
    for (int i = 0; i < byteArray.Length; i++)
    {
        byteArray[i] = (byte) sbyteArray[i];
    }
    return byteArray;
}
公共静态字符串ByteArrayToHexString(sbyte[]byteArray)
{
返回BitConverter.ToString(convert(byteArray)).Replace(“-”,”);//转换整个数组
}
公共静态sbyte[]HexStringToByteArray(字符串hexString)
{
byte[]HexAsBytes=新字节[hexString.Length/2];
for(int index=0;index
但是,当我在两种语言上将相同的十六进制值转换为字节数组时,输出是不同的

您所看到的是,字节在Java中是有符号的,在C#中是无符号的。因此,如果在Java中向任何负值添加256,将得到C#中显示的值。值中的实际位是相同的-只是顶部位是否被视为符号位的问题

编辑:如注释中所述,如果在调试器输出之外使用字节作为整数,则始终可以使用:

int someInt = someByte & 0xff;

获取无符号值。

看起来这只是调试器的问题。在Java调试器中看到的那些负值与在C#调试器中看到的无符号值是有符号的等价物。例如,有符号字节-9==无符号字节247(请注意,它们总是相差256)。数据很好。

在Java中,不需要在任何负字节值上加256,而是可以获得一个
int
值,该值等于存储在任何字节值
b
中的位的无符号值,并且
(b&0xff)
@TedHopp:确实如此。但调试器的输出并没有帮助。不过,我将添加一条注释。谢谢您的提示。我用答案更新了我的问题。我在C#中从byte[]改为sbyte[]。作为旁注,鲜为人知的类是以示例中显示的格式将字符串转换为十六进制并返回的最简单方法之一。该类已在.NET framework seance 1.0中使用。
        String hexString = "65F70BAD2E4A3889B92628BFCC68539A";
        byte[] byteArray = HexBytes.HexStringToByteArray(hexString);
        //Using the debugger, byteArray = [101, 247, 11, 173, 46, 74, 56, 137, 185, 38, 40, 191, 204, 104, 83, 154]
        String hexString2 = HexBytes.ByteArrayToHexString(byteArray)
        Console.Write("HEX: " + hexString2);
        //Outputs 65F70BAD2E4A3889B92628BFCC68539A
    String hexString = "65F70BAD2E4A3889B92628BFCC68539A";
    byte[] byteArray = HexBytes.HexStringToByteArray(hexString);
    //Using the debugger, byteArray = [101, -9, 11, -83, 46, 74, 56, -119, -71, 38, 40, -65, -52, 104, 83, -102]
    String hexString2 = HexBytes.ByteArrayToHexString(byteArray);
    System.out.println("HEX: " + hexString2);
    //Outputs 65F70BAD2E4A3889B92628BFCC68539A
public static string ByteArrayToHexString(sbyte[] byteArray)
{
    return BitConverter.ToString(convert(byteArray)).Replace("-", ""); //To convert the whole array
}

public static sbyte[] HexStringToByteArray(string hexString)
{

    byte[] HexAsBytes = new byte[hexString.Length / 2];
    for (int index = 0; index < HexAsBytes.Length; index++)
    {
        string byteValue = hexString.Substring(index * 2, 2);
        HexAsBytes[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
    }

    return convert(HexAsBytes);
}


private static sbyte[] convert(byte[] byteArray)
{
    sbyte[] sbyteArray = new sbyte[byteArray.Length];
    for (int i = 0; i < sbyteArray.Length; i++)
    {
        sbyteArray[i] = unchecked((sbyte) byteArray[i]);
    }

    return sbyteArray;
}

private static byte[] convert(sbyte[] sbyteArray)
{
    byte[] byteArray = new byte[sbyteArray.Length];
    for (int i = 0; i < byteArray.Length; i++)
    {
        byteArray[i] = (byte) sbyteArray[i];
    }
    return byteArray;
}
int someInt = someByte & 0xff;