Why does bytes data change during conversion between bytes and strings?

Viewed 380

I've found a phenomenon I can't really understand in Java and I post a question

  1. Put some data into the byte array
  2. Convert byte array to string
  3. Convert the converted string back to a byte array
  4. When comparing the first data and the data after conversion, some of them will be output differently.

The source code and log are below

Source code

// 1. Input byte array data
byte[] beforeBytes = new byte[]{(byte)-83, (byte)-95, (byte)-55, (byte)-49, (byte)3};
log.info("Before ByteTest");
log.info("bytesLength : " + beforeBytes.length);
for (int i = 0; i < beforeBytes.length; ++i)
{
    log.info(i + " : " + (int)beforeBytes[i]);
}

// 2. Convert byte array to string
String testString = new String(beforeBytes);

// 3. Convert string to byte array
byte[] afterBytes = testString.getBytes();
log.info("After ByteTest");
log.info("bytesLength : " + afterBytes.length);
for (int i = 0; i < afterBytes.length; ++i)
{
    log.info(i + " : " + (int)afterBytes[i]);
}

Log

Before ByteTest
bytesLength : 5
0 : -83
1 : -95
2 : -55
3 : -49
4 : 3

After ByteTest
bytesLength : 5
0 : 63
1 : -95
2 : -55
3 : 63
4 : 3

I want to keep the same data as the existing data even after conversion Is there a workaround?

1 Answers

You should use a encoder and decoder like this:

        // 2. Convert byte array to string
    String testString = Base64.getEncoder().encodeToString(beforeBytes);

    // 3. Convert string to byte array
    byte[] afterBytes = Base64.getDecoder().decode(testString);

So finally your code will be like this:

    // 1. Input byte array data
    byte[] beforeBytes = new byte[]{(byte)-83, (byte)-95, (byte)-55, (byte)-49, 
    (byte)3};
    log.info("Before ByteTest");
    log.info("bytesLength : " + beforeBytes.length);
    for (int i = 0; i < beforeBytes.length; ++i)
    {
        log.info(i + " : " + (byte)beforeBytes[i]);
    }

    // 2. Convert byte array to string
    String testString = Base64.getEncoder().encodeToString(beforeBytes);

    // 3. Convert string to byte array
    byte[] afterBytes = Base64.getDecoder().decode(testString);
    log.info("After ByteTest");
    log.info("bytesLength : " + afterBytes.length);
    for (int i = 0; i < afterBytes.length; ++i)
    {
        log.info(i + " : " + (byte)afterBytes[i]);
    }

The method that you was using .getBytes() is not the most appropriate because you didn't write in the constructor the charSet like UTF-8 for example and the constructor can add or modify some of the data. Using the Base64 encoder and decoder is much better. Kind regards.

Related