6

TLDR: Java is signed, c# is unsigned. Byte[] values are different, how to solve this. How can I convert either side to the other?

Values are of "Hello World" MD5 hashed and then converted to bytes

Java:

-79, 10, -115, -79, 100, -32, 117, 65, 5, -73, -87, -101, -25, 46, 63, -27

C#:

177, 10, 141, 177, 100, 224, 117, 65, 5, 183, 169, 155, 231, 46, 63, 229

I use the byte[] to encrypt using AES on both sides but the passwords never match.

8
  • stackoverflow.com/questions/2920044/… Commented May 24, 2016 at 10:47
  • The values aren't different. They're represented differently. You can be sure that the bits are exactly same. Commented May 24, 2016 at 10:48
  • My hashes match, my bytes don't. I don't see anything helpfull in that post. Commented May 24, 2016 at 10:49
  • My post is targeted at Sarathy, sorry Kayaman. Commented May 24, 2016 at 10:52
  • 1
    @user5581557, that's wrong. If you're having problems decrypting the file in Java, it's not because Java uses signed bytes. Commented May 24, 2016 at 18:17

2 Answers 2

8

The bytes have identical values, they are just printed differently.

If you would like to ensure that bytes with negative values are displayed as positive numbers, add 256 and take modulo 256, like this:

for (byte b : byteArray) {
    int n = (b + 256) % 256;
    System.out.println(n);
}

Similarly, if you would like to bring your values above 128 into the proper range of byte, you can cast them to truncate the upper bytes and get negative values, or if you prefer you could subtract 256:

for (int n : byteValuesAsInt) {
    byte b1 = (byte)n;
    byte b2 = n >= 128 ? n-256 : n;
}
Sign up to request clarification or add additional context in comments.

3 Comments

My objective is not to view the bytes, its to use them. In Java I cannot insert the values into a byte[] as It's unsigned.
Of course you can. Just cast them down to a byte. Whether it will end as a negative number is not relevant - the bytes representation is the same.
Could you show an example of "casting down to a byte" please.
3

Java uses signed bytes, while C# uses unsinged ones. To compare strings, let's convert Java representation to C# one:

  String java = 
    "-79, 10, -115, -79, 100, -32, 117, 65, 5, -73, -87, -101, -25, 46, 63, -27";

  String cs = String.Join(", ", java
    .Split(',')
    .Select(c => int.Parse(c))
    .Select(x => x < 0 ? 256 + x: x));

 // 177, 10, 141, 177, 100, 224, 117, 65, 5, 183, 169, 155, 231, 46, 63, 229
 Console.Write(cs);

As you can see the strings are now equal.

EDIT: If you're given java string, and you want to have C# byte[]:

 byte[] cs = java
   .Split(',')
   .Select(c => int.Parse(c))
   .Select(x => (byte) (x < 0 ? 256 + x: x)))
   .ToArray();

2 Comments

Okay thats perfect, but how can I use that string (result) in a function which takes a byte[] as a parameter? ex: decrypt(byte[],byte[])
@user5581557: if you're given Java string (since there're negative values in the Java result you can't have byte[] in C# directly) you can convert it into c# byte[] via Linq (see my edit)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.