1

I need some consulting here.

I'm writing a client/server software.

One requirement is to use an XML file to transfer information between the client and the server. This decision was made to allow clients to be created on any language. I know I could use json for simpler communication, but I needed a better Object to Text Mapping, so I ended up with XML. So, to diminish the XMl size problem, I decided to compress it before sending over socket. On top of it, I want to encrypt the data so it will be harder to be broken by some interceptor. I have read a lot about encrypting and encryption types, but for testing purposes I'll just use Base64 and generic compression just to join up all the technologies, than I'll specialize the specifics. I found a lot of code and good advice here on stack exchange, and now I'm having some trouble.

What I have:

  • In memory Objects;
  • Static methods to convert Objects to XML in memory;
  • No use for Serialization because the clients can be written on C, .net, perl, etc;
  • Avoid disk write to reduce disk I/O, keeping everything in-memory;
  • The need to work with punctuation chars (UTF-8);
  • The need to work with stronger encrypt on the future;

The process I idealized is:

  1. Convert object to XML - OK
  2. Establish Client/server communication - OK
  3. Encode XML String to Base64 - OK (no compression)
    • 3.1. Compress XML String and than encode to Base64 - OK
  4. Transfer between client/server - OK
  5. Decode Base64 String to XML String - OK
    • 5.1. Uncompress transferred byte array and decode Base64 - NOT OK

So, I can't find where I'm getting wrong on the "Compress String -> Encode it to Base64 -> transmit -> decode Base64 to String -> uncompress it" process... Here is the snippet from my code "inspired" on stack overflow:

I'm using this answer (with .net compatibility) as a reference to compress/uncompress: How can I Zip and Unzip a string using GZIPOutputStream that is compatible with .Net?

public class Compressor2 {

public static byte[] compress(String string) throws IOException {
    byte[] blockcopy = ByteBuffer
            .allocate(4)
            .order(java.nio.ByteOrder.LITTLE_ENDIAN)
            .putInt(string.length())
            .array();
    ByteArrayOutputStream os = new ByteArrayOutputStream(string.length());
    GZIPOutputStream gos = new GZIPOutputStream(os);
    gos.write(string.getBytes());
    gos.close();
    os.close();
    byte[] compressed = new byte[4 + os.toByteArray().length];
    System.arraycopy(blockcopy, 0, compressed, 0, 4);
    System.arraycopy(os.toByteArray(), 0, compressed, 4, os.toByteArray().length);
    compressed = MyBase64.encode(new String(compressed)).getBytes();
    return compressed;
}

public static String decompress(byte[] compressed) throws IOException {
    compressed = MyBase64.decode(new String(compressed)).getBytes();
    System.out.println(compressed);
    System.out.println(new String(compressed));
    final int BUFFER_SIZE = 32;
    //ByteArrayInputStream is = new ByteArrayInputStream(compressed, 4, compressed.length - 4);
    ByteArrayInputStream is = new ByteArrayInputStream(compressed);
    GZIPInputStream gis = new GZIPInputStream(is, BUFFER_SIZE);
    StringBuilder string = new StringBuilder();
    byte[] data = new byte[BUFFER_SIZE];
    int bytesRead;
    while ((bytesRead = gis.read(data)) != -1) {
        string.append(new String(data, 0, bytesRead));
    }
    gis.close();
    is.close();
    return string.toString();
}

from MyBase 64:

public static String encode(String text) throws UnsupportedEncodingException {
    byte[] encodedBytes = Base64.encodeBase64(text.getBytes());
    return new String(encodedBytes, "UTF-8");
}

public static String decode(String text) throws UnsupportedEncodingException {
    byte[] decodedBytes = Base64.decodeBase64(text);
    return new String(decodedBytes, "UTF-8");
}

and the test case:

 /**
 * Test of compress method, of class Compressor2.
 */
@Test
public void testCompress() throws Exception {
    System.out.println("compress");
    String string = "Hello all, how can I transfer this with punctuation? like á é í ó ú";
    byte[] expResult = Compressor2.compress(string);
    byte[] result = Compressor2.compress(string);
    System.out.write(result);
    System.out.print("\n");
    System.out.println(new String(result));
    assertArrayEquals(expResult, result);
    for (byte character : result) {
        System.out.print(String.valueOf(character));
    }
    System.out.print("\n");
    for (byte character : result) {
        System.out.print((character));
    }
    System.out.print("\n");
}

/**
 * Test of decompress method, of class Compressor2. 
 */
@Test
public void testDecompress() throws Exception {
    System.out.println("decompress");
    String expResult = "Hello all, how can I transfer this with punctuation? like á é í ó ú";
    //String expResult = "The lazy dog ate an apple";
    byte[] compressed = Compressor2.compress(expResult);

    System.out.println(expResult);
    System.out.write(compressed);
    System.out.print("\n");
    System.out.println("going to decompress");
    String result = Compressor2.decompress(compressed);
    System.out.println(result);
    assertEquals(expResult, result);
    // TODO punctuation errors? 
}

System Out for checking the values:

compress
QwAAAB/vv70IAAAAAAAAAAXvv73vv70N77+9MAwE77+9VX4Adu+/ve+/vTHvv73vv70oFu+/vRMl77+9Mg8lBRUd77+9F++/vW5j77+9AlJd77+977+9RCLvv70Ob2Tvv73vv70G77+977+9Me+/vTPvv73vv71c77+977+9UDkZcSFuxIN4Ee+/vQ/nn5ENSAAAAA==
QwAAAB/vv70IAAAAAAAAAAXvv73vv70N77+9MAwE77+9VX4Adu+/ve+/vTHvv73vv70oFu+/vRMl77+9Mg8lBRUd77+9F++/vW5j77+9AlJd77+977+9RCLvv70Ob2Tvv73vv70G77+977+9Me+/vTPvv73vv71c77+977+9UDkZcSFuxIN4Ee+/vQ/nn5ENSAAAAA==
811196565656647118118554873656565656565656565658811811855511181185548785555435777651196955554357868852651001174347118101434711884721181185551118118554811170117434711882771085555435777103561086682851005555435770434347118875310655554357651087410055554357555543578267761181185548799850841181185551118118554871555543575555435777101434711884801181185551118118554999555543575555435785681079099837011712073785269101434711881471101105369788365656565656161
811196565656647118118554873656565656565656565658811811855511181185548785555435777651196955554357868852651001174347118101434711884721181185551118118554811170117434711882771085555435777103561086682851005555435770434347118875310655554357651087410055554357555543578267761181185548799850841181185551118118554871555543575555435777101434711884801181185551118118554999555543575555435785681079099837011712073785269101434711881471101105369788365656565656161
decompress
Hello all, how can I transfer this with punctuation? like á é í ó ú
QwAAAB/vv70IAAAAAAAAAAXvv73vv70N77+9MAwE77+9VX4Adu+/ve+/vTHvv73vv70oFu+/vRMl77+9Mg8lBRUd77+9F++/vW5j77+9AlJd77+977+9RCLvv70Ob2Tvv73vv70G77+977+9Me+/vTPvv73vv71c77+977+9UDkZcSFuxIN4Ee+/vQ/nn5ENSAAAAA==
going to decompress
[B@19f9bdc4
C

Sorry for the long post, I'm trying to give you something to work on to check where I'm getting this wrong. I Appreciate any help...

Edit.: Forgot to say, if you take the "MyBase64.decode or encode" line from the Compressor2 Classe, it works like a charm...

Community
  • 1
  • 1
Titusfr
  • 11
  • 2
  • Don't use `String` to store binary data! – fge Oct 28 '14 at 18:54
  • I'm not, XML are Strings, I'm just getting it as array of bytes to encrypt, compress and transmit... – Titusfr Oct 28 '14 at 18:59
  • http://stackoverflow.com/help/mcve - creating a code snippet that consists of the program output just makes no sense at all. – Maarten Bodewes Oct 28 '14 at 21:28
  • Thanks for the tip. I didn't find any "object" to insert that block of sysout... Where could I find this "" block? – Titusfr Oct 28 '14 at 22:03
  • @Titusfr On meta: http://meta.stackexchange.com/questions/184108/what-is-syntax-highlighting-and-how-does-it-work – Maarten Bodewes Oct 28 '14 at 22:06
  • @Titusfr I don't think the output completely matches the code. Note that printing out all the byte values of a byte array as decimals all concatenated together doesn't make much sense. Furthermore, printing out a byte array directly will just print out `[B@` followed by the `hashCode` of the object. I don't know where that final C came from (is it maybe your console?) – Maarten Bodewes Oct 29 '14 at 01:00

0 Answers0